var Users = mongoose.model('user');
var fs = require("fs");
var async = require('async');
var path = require('path');
var Community = mongoose.model('community');
var userService = require('../services/userService');
var UserFollowups = mongoose.model('user_followups');
var toolUtil = require('../common/utils/toolUtil');
var mysqlUtil = require('../common/utils/mysqlUtil');
var messageUtil = require('../common/utils/messageUtil');
var Question = mongoose.model('question');
var cacheUtil = require('../common/utils/cacheUtil');
var SystemMessage = mongoose.model('system_messages');
var Activity = mongoose.model('activity');
var moment = require('moment');
var SystemBanner = mongoose.model('system_BannerDefinitions');
var Bulletins = mongoose.model('community_bulletins');
var questionService = require('../services/questionService');
var Relation = mongoose.model('Relation_userAcitvity');
var QuestionReplyStatistics = mongoose.model('question_replystatistics');
var appHomeModules = mongoose.model('system_appHomeModules');
var userPortrait = mongoose.model('masterData_UserPortrait');
var adminUsers = mongoose.model('backoffice_adminusers');
var QuestionReplyPraise = mongoose.model('question_replypraises');
var userAuthentication = mongoose.model('user_authentications');
var md5 = require('MD5');
var specialTopics = mongoose.model('system_specialTopics');
var freshNews = mongoose.model('system_freshNews');
var roleAction = mongoose.model('masterData_roleActions');
var userCommunity = mongoose.model('user_community');
var ugcIndex = mongoose.model('system_ugcIndex');
var neighbourActivity = mongoose.model('activity_neighbour');
var ugcReply = mongoose.model('system_ugcReply');
var promotionCode = mongoose.model('system_promotionCode');
var AdoptedCount = mongoose.model('question_adoptedcounts');
//var pinyin = require("pinyin");
var inviteBind = mongoose.model('invite_wechat_bind');
var deviceCodeBind = mongoose.model('relation_deviceCodeBind');
var chatMessage = mongoose.model('system_chatMessages');
var recentContact = mongoose.model('user_recentContactPerson');
var replyAt = mongoose.model('question_replyAt');
var Banner = mongoose.model('community_banner');
var BannerBind = mongoose.model('community_banner_bind');

/*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  start   */
// 共同方法，小区大使数据统计，小区大使操作记录
var ModeratorManager = mongoose.model('moderatorManager'); // 小区大使置顶精华屏蔽数据
var ModeratorManagerOperationNote = mongoose.model('moderatorManagerOperationNote'); // 小区大使置顶精华屏蔽操作记录
// req, 用户ID, ['top':置顶, 'essence':精华, 'shielding':屏蔽], [1:置顶,设置精华,屏蔽; -1:取消置顶,取消精华,取消屏蔽], callback
exports.incModeratorManager = function(userId, incType, addFlag, callback) {
    var option = {'user' : userId};
    ModeratorManager.count(option, function (err, count) {
        if(count > 0) {
            var opt = {};
            if(incType == 'top') {
                opt.topCount = addFlag;
            } else if(incType == 'essence') {
                opt.essenceCount = addFlag;
            } else if(incType == 'shielding') {
                opt.shieldingCount = addFlag;
            }
            ModeratorManager.update(option, {$inc : opt}).exec(callback);
        } else {
            var temp = new ModeratorManager();
            temp.user = userId;
            temp.topCount = 0;
            temp.essenceCount = 0;
            temp.shieldingCount = 0;
            if(incType == 'top') {
                temp.topCount = addFlag;
            } else if(incType == 'essence') {
                temp.essenceCount = addFlag;
            } else if(incType == 'shielding') {
                temp.shieldingCount = addFlag;
            }
            temp.save(callback);
        }
    });
};

// 小区大使置顶精华屏蔽操作记录
exports.saveModeratorManagerOperationNote = function(userId, questionId, operationType, callback) {
    var temp = new ModeratorManagerOperationNote();
    temp.user = userId; // 用户ID
    temp.question = questionId; // 问题ID
    temp.operationType = operationType; // 操作记录类型
    temp.dateCreated = Date.now(); // 创建时间
    temp.save(callback);
};
/*  宝宝树66小区二次改造    mod   guo.xiaomin  20170825  end   */

exports.registerService = function (userName, email, mobilePhone, userPassword, clientId, callback) {

    var args = {
        data: {
            username: mobilePhone,
            password: mobilePhone
        },
        headers: {"Content-Type": "application/json"}
    };
    restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/users", args, function (data, response) {
        if (response.statusCode = 200) {
            toolUtil.getInvitationCode(function (err, code) {
                var tempUser = new Users();
                tempUser.userName = userName;
                tempUser.email = email;
                tempUser.mobilePhone = mobilePhone;
                tempUser.userPassword = userPassword;
                tempUser.invitationCode = code;
                var img = {
                    "imageURL": defaultImage
                };
                tempUser.images.push(img);
                tempUser.clientId = clientId;
                if (userName) {
                    tempUser.huanxinUserName = userName;
                } else if (email) {
                    tempUser.huanxinUserName = email;
                } else {
                    tempUser.huanxinUserName = mobilePhone;
                }
                tempUser.save(callback);
            });
        } else {
            var msg = {
                "message": "用户名已存在"
            };
            callback(msg, null);
        }
    }).on('error', function (err) {
        logger.error(err);
        var msg = {
            "message": "用户名已存在"
        };
        callback(msg, null);
    });
};

exports.bindClientIdService = function (clientId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null);
        } else {
            async.series([
                function (callbackInner) {
                    Users.find({clientId: clientId}, '_id clientId', function (err, users) {
                        if (users != null && users.length > 0) {
                            async.each(users, function (user, callback1) {
                                user.clientId = undefined;
                                user.save(callback1);
                            }, function (err) {
                                callbackInner(err, null);
                            })
                        } else {
                            callbackInner(err, null);
                        }
                    })
                },
                function (callbackInner) {
                    Users.update({_id: user._id}, {clientId: clientId}, callbackInner);
                }
            ], callback);
        }
    });
};

exports.checkTokenService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null)
        } else {
            async.series([
                function (callbackInner) {
                    callbackInner(null, user);
                },
                function (callbackInner) {
                    var role;
                    if (user.authenticationStatus) {
                        role = 'vip'
                    } else {
                        role = 'normal'
                    }
                    var data = [];
                    roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                        if (results != null) {
                            results.forEach(function (temp) {
                                data.push(temp.action.tag);
                            })
                        }
                        callbackInner(err, data);
                    });
                },
                function (callbackInner) {
                    if (user.community) {
                        userAuthentication.findOne({
                            user: user._id,
                            isValid: true,
                            community: user.community._id
                        }, 'status', function (err, result) {
                            var data;
                            if (result == null) {
                                data = 0
                            } else {
                                if (result.status) {
                                    data = 1
                                } else {
                                    data = 2
                                }
                            }
                            callbackInner(err, data);
                        })
                    } else {
                        callbackInner(null, 0);
                    }
                },
                function (callbackInner) {
                    var key = 'app:signin:' + moment().format('YYYYMMDD');

                    redisClient.SISMEMBER(key, token, function (err, result) {
                        if (result == 1) {
                            callbackInner(null, true)
                        } else {
                            callbackInner(null, false)
                        }
                    });
                }
            ], callback)
        }
    });
};

exports.checkTokenNewService = function (password, token, callback) {

};

exports.sendWelcomeNewsService = function (mobilePhone, callback) {
    Users.findOne({'nickName': '小6客服'}, function (err, result) {
        userService.addToContactListService(result._id, '66CustomerService', mobilePhone, function (err) {
            if (err) {
                callback(err, null);
            } else {
                toolUtil.getAndCacheHuanXinToken(function (err, token) {
                    var args = {
                        data: {
                            "target_type": "users",
                            "target": [mobilePhone],
                            "msg": {
                                "type": "txt",
                                /*  宝宝树66小区二次改造    mod   zhangm  20170721   start   */
                                "msg": "欢迎加入宝宝树66小区，在这里，你可以跟邻居宝妈一起交流育儿经验、发现周围好玩、好吃、好逛的亲子活动信息、让闲置变废为宝……更多功能等你开启，快去逛溜吧！"
                                /*  宝宝树66小区二次改造    mod   zhangm  20170721   start   */

                            },
                            "from": result.huanxinUserName,
                            "ext": {           //扩展属性, 由app自己定义.可以没有这个字段，但是如果有，值不能是“ext:null“这种形式，否则出错
                                "nickName": "小6客服",
                                "avatar": result.images[0].imageURL,
                                "objId": result._id
                            }
                        },
                        headers: {
                            "Content-Type": "application/json",
                            "Authorization": "Bearer " + token
                        }
                    };

                    restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/messages", args, function (data, response) {
                        callback(null, null);
                    }).on('error', function (err) {
                        logger.error('sendWelcomeNewsService' + err.message);
                    });
                });
            }
        })
    });
};

/**
 * userService.js
 *删除用户
 * @param userName
 * @param email
 * @param mobilePhone
 * @param callback
 *author：chenjinzhuan
 * */
exports.deleteService = function (userName, email, mobilePhone, callback) {
    Users.findOneAndRemove({userName: userName, email: email, mobilePhone: mobilePhone}, callback);
};

/**
 * userService.js
 *获取环信app的token
 *author：chenjinzhuan
 * */
exports.getHuanxinTokenService = function (callback) {
    //环信获取token开始

    toolUtil.getAndCacheHuanXinToken(function (err, token) {
        callback(err, token)
    });

};

exports.findByIdService = function (id, callback) {

    Users.findById(id, 'userName email mobilePhone birthDate nickName age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy userRole dateCreated')
        .populate('userPortrait', 'portraitURL value').populate('community', 'id communityName communityType communityAddress unitSwitch communityLogo cityId  provinceId countyId location price dateBuild').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value').exec(function (err, result) {
            if (result != null && !result.authenticationStatus) {
                result.invitationCode = undefined;
            }
            callback(err, result);
        });
};

exports.findPushTokenService = function (userId, callback) {
    Users.findById(userId, 'baiduMessagePushingToken').exec(callback)
};

exports.logoutService = function (token, callback) {
    async.series([

        function (callbackInner) {
            cacheUtil.cacheDelete(token, callbackInner);
        },
        function (callbackInner) {
            Users.findOne({_id: toolUtil.getUserObjIdByToken(token)}, '_id clientId huanxinUserName', function (err, user) {
                user.clientId = undefined;
                user.save(callbackInner);
            })
        }
    ], callback)
};

exports.loginService = function (loginId, password, clientId, callback) {
    async.series([
            function (callbackInner) {
                Users.findOne({
                    mobilePhone: loginId,
                    userPassword: password
                }, '_id userName frozenOrNot email mobilePhone birthDate nickName age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus')
                    .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName communityAddress').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value').exec(callbackInner);
            },
            function (callbackInner) {
                if (clientId != null) {
                    Users.update({
                        $or: [{mobilePhone: loginId, userPassword: password}, {
                            wechatId: loginId,
                            userPassword: password
                        }]
                    }, {clientId: clientId}, callbackInner)
                } else {
                    callbackInner(null, null);
                }

            }
        ],
        callback);
};

//新登录
exports.appLoginService = function (loginId, password, thirdId, callback) {
    var user;
    var opt = {};
    if (loginId != null) {
        opt = {
            mobilePhone: loginId,
            userPassword: password
        }
    } else if (thirdId != null) {
        opt = {
            wechatId: thirdId
        }
    }
    async.series([
        function (callbackInner) {
            Users.findOne(opt, '_id userName frozenOrNot email mobilePhone birthDate nickName age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus roomUnit roomNumber showUnit invitationCode invitedBy')
                .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName communityAddress communityLogo unitSwitch').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value')
                .exec(function (err, result) {
                    if (result != null && !result.authenticationStatus) {
                        result.invitationCode = undefined;
                    }
                    user = result;
                    callbackInner(err, user);
                });
        },
        function (callbackInner) {
            if (user != null) {
                var role;
                if (user.authenticationStatus) {
                    role = 'vip'
                } else {
                    role = 'normal'
                }
                var data = [];
                roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                    if (results != null) {
                        results.forEach(function (temp) {
                            data.push(temp.action.tag);
                        })
                    }
                    callbackInner(err, data);
                });
            } else {
                callbackInner(null, null);
            }
        },
        function (callbackInner) {
            if (user && user.community) {
                userAuthentication.findOne({
                    user: user._id,
                    isValid: true,
                    community: user.community._id
                }, 'status', function (err, result) {
                    var data;
                    if (result == null) {
                        data = 0
                    } else {
                        if (result.status) {
                            data = 1
                        } else {
                            data = 2
                        }
                    }
                    callbackInner(err, data);
                })
            } else {
                callbackInner(null, 0);
            }
        },
        function (callbackInner) {
            var key = 'app:signin:' + moment().format('YYYYMMDD');

            if (user != null) {
                redisClient.SISMEMBER(key, user._id + '', function (err, result) {
                    if (result == 1) {
                        callbackInner(null, true)
                    } else {
                        callbackInner(null, false)
                    }
                });
            } else {
                callbackInner()
            }
        }
    ], callback);
};

/**
 * 获取用户权限列表
 * @param token
 * @param callback
 */
exports.getUserAuthListService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            Users.findOne({_id: user._id}, function (err, result) {
                var role;
                if (result.authenticationStatus) {
                    role = 'vip'
                } else {
                    role = 'normal'
                }
                var data = [];
                roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
                    if (results != null) {
                        results.forEach(function (temp) {
                            data.push(temp.action.tag);
                        })
                    }
                    callback(err, data);
                });
            });
        }
    })
};

/**
 * 第三方登录接口 1.1.2开始
 */
exports.appThirdPartyLoginService = function (thirdId, input, deviceId, callback) {
    var isRegister;
    async.series([
        function (callbackInner) {
            Users.findOne({wechatId: thirdId}, function (err, result) {
                isRegister = result ? false : true;
                callbackInner(null, null);
            });
        },
        function (callbackInner) {
            if (isRegister) {
                var args = {
                    data: {
                        username: thirdId,
                        password: thirdId
                    },
                    headers: {"Content-Type": "application/json"}
                };
                restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/users", args, function (data, response) {
                    if (response.statusCode == 200) {
                        toolUtil.getInvitationCode(function (err, code) {

                            var regStr = '^' + thirdId + '$';
                            inviteBind.findOne({unionId: {$regex: regStr, $options: "$i"}}, function (err, bind) {

                                var tempUser = new Users();
                                tempUser.huanxinUserName = thirdId;
                                tempUser.huanxinPassword = thirdId;
                                tempUser.wechatId = thirdId;
                                tempUser.userPassword = md5(thirdId);
                                tempUser.nickName = input.nickName;

                                //tempUser.pinyin = pinyin(input.nickName, {style: pinyin.STYLE_NORMAL}).join('').toLowerCase();
                                //tempUser.pinyinShort = pinyin(input.nickName, {style: pinyin.STYLE_FIRST_LETTER}).join('');
                                //tempUser.pinyinSort = tempUser.pinyin + '_' + (new Date()).getTime();

                                tempUser.openId = input.openId;
                                tempUser.loginWay = input.loginWay;
                                tempUser.invitationCode = code;
                                if (input.image == null || input.image == '') {
                                    input.image = defaultImage;
                                }
                                var img = {
                                    "imageURL": input.image
                                };
                                tempUser.images.push(img);

                                if (bind && bind.fromUserId) {
                                    tempUser.invitedBy = bind.fromUserId;
                                }

                                tempUser.save(function (err, result) {
                                    redisClient.sadd('u:all', result._id);
                                    callbackInner(null, isRegister);

                                    if (bind && bind.inviteCode) {
                                        var temp = new deviceCodeBind();
                                        temp.invitationCode = bind.inviteCode;
                                        temp.deviceId = deviceId;
                                        temp.user = result._id;
                                        temp.save();
                                    }
                                });
                            });
                        })
                    } else {
                        var msg = {
                            "message": "登录失败"
                        };
                        callbackInner(msg, null);
                    }
                }).on('error', function (err) {
                    logger.error('init community around went wrong on the request' + err.message);
                    var msg = {
                        "message": "登录失败"
                    };
                    callbackInner(msg, null);
                });
            } else {
                callbackInner(null, isRegister);
            }
        },
        function (callbackInner) {
            userService.appLoginService(null, null, thirdId, function (err, results) {
                var user = results[0];
                if (user.frozenOrNot) {
                    var msg = {
                        message: '帐号被冻结'
                    };
                    callbackInner(msg, null);
                } else {
                    var token = results[0]._id;
                    //获取token并缓冲
                    user.frozenOrNot = undefined;
                    user._doc['token'] = token;
                    user._doc['auth'] = results[1];
                    user._doc['vStatus'] = results[2];
                    user._doc['isSignIn'] = results[3];

                    toolUtil.setUserByToken(token);

                    callbackInner(err, user);
                }
            });
        }
    ], callback)
};

/**
 * userService.js
 *微信登录
 *author：chenjinzhuan
 * */
exports.loginViaWeChatService = function (wechatId, nickName, image, clientId, callback) {

    wechatId = wechatId.toLowerCase();

    if (nickName == null) {
        var msg = {
            "message": "没有昵称"
        };
        callback(msg, null);
    } else {
        //根据微信统一id查找用户

        Users.findOne({wechatId: wechatId}, '_id userName frozenOrNot email mobilePhone birthDate nickName age gender maritalStatus hasChildren images apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county huanxinUserName appSetting userType speciality userPortrait job school authenticationStatus')
            .populate('userPortrait', 'portraitURL value').populate('community', '_id communityName communityAddress').populate('homeTown.country', '_id name').populate('homeTown.province', '_id name').populate('homeTown.city', '_id name').populate('homeTown.county', '_id name').populate('hobbies', '_id value')
            .exec(function (err, user) {
                if (err) {//查找出错的情况
                    logger.error('Exception happened in getContactListService...!');
                    return callback(err, null);
                } else if (user == null) {//用户不存在，则建立新用户
                    logger.debug('create a new wechat account...!');
                    var args = {
                        data: {
                            username: wechatId,
                            password: wechatId
                        },
                        headers: {"Content-Type": "application/json"}
                    };
                    restClient.post("http://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/users", args, function (data, response) {
                        if (response.statusCode == 200) {
                            var tempUser = new Users();
                            tempUser.huanxinUserName = wechatId;
                            tempUser.huanxinPassword = wechatId;
                            tempUser.wechatId = wechatId;
                            tempUser.userPassword = md5(wechatId);
                            tempUser.nickName = nickName;
                            tempUser.clientId = clientId;
                            var images = [];
                            var img = {
                                "imageURL": image
                            };
                            tempUser.images.push(img);
                            tempUser.save(function (err, result) {
                                tempUser._doc['_id'] = result._id;
                                tempUser._doc['firstLogin'] = true;
                                callback(null, tempUser);
                            });

                        } else {
                            var msg = {
                                "message": "登录失败"
                            };
                            callback(msg, null);
                        }
                    }).on('error', function (err) {
                        logger.error('init community around went wrong on the request' + err.message);
                        var msg = {
                            "message": "登录失败"
                        };
                        callback(msg, null);
                    });

                } else {//用户存在，则返回用户的所有数据
                    //如果用户被冻结，则返回错误
                    if (user._doc.frozenOrNot == true) {
                        var msg = {
                            "message": "帐号被冻结"
                        };
                        callback(msg, null);
                    } else {
                        if (user._doc.nickName == null && nickName != null) {//如果昵称不存在，就添加昵称
                            Users.update({_id: user._id}, {'nickName': nickName}, function (err) {
                                if (err) {
                                    logger.debug("login by wechat wrong" + err);
                                }
                            });
                            user._doc["nickName"] = nickName;
                        }
                        if (user.images.length == 0 && image != null) {//如果头像不存在，就添加头像
                            var images = [];
                            var img = {
                                "imageURL": image
                            };
                            images.push(img);
                            Users.update({_id: user._id}, {$set: {'images': images}}, function (err) {
                                if (err) {
                                    logger.debug("login by wechat wrong" + err);
                                }
                            });
                            user._doc["images"] = images;
                        }
                        user._doc["firstLogin"] = false;
                        callback(null, user);
                    }
                }
            });
    }
};

exports.getUserAuthService = function (status, callback) {
    var role;
    if (status) {
        role = 'vip'
    } else {
        role = 'normal'
    }

    var data = [];
    roleAction.find({role: role}).populate('action', 'tag').exec(function (err, results) {
        if (results != null) {
            results.forEach(function (temp) {
                data.push(temp.action.tag);
            })
        }
        callback(err, data);
    });
};

/**
 * userService.js
 *重置密码
 *author：chenjinzhuan
 * */
exports.resetPasswordService = function (mobilePhone, newPassword, callback) {
    async.waterfall([
        //更新数据库密码
        function (callbackInner) {
            Users.update({mobilePhone: mobilePhone}, {userPassword: md5(newPassword)}, function (err) {
                if (err) {
                    logger.debug('Exception happened in resetPasswordService 1....');
                    return callback(err);
                } else {
                    logger.debug('succeed to reset the password in database ...');
                    callbackInner(null);
                }
            });
        },
        //更新最后修改日期
        function (callbackInner) {
            Users.update({mobilePhone: mobilePhone}, {dateLastModified: new Date()}, function (err) {
                if (err) {
                    logger.debug('Exception happened in resetPasswordService 2....');
                    return callback(err);
                } else {
                    logger.debug('succeed to change the dateLastModified ...');
                    callbackInner(null);
                }
            });
        }
    ], callback);
};


/**
 * userService.js
 *修改密码
 *author：chenjinzhuan
 * */
exports.changePaswordService = function (id, userName, input, callback) {
    //所有的回调函数都应该有单独的函数实现，例如：function(err,user){}
    //回调函数如果加return，则会返回到对应的函数，如果不加return，则会继续执行
    async.waterfall([
        //查询旧密码
        function (callbackInner) {

            Users.findOne({_id: id}, 'userPassword', function (err, result) {
                callbackInner(null, result);
            })
        },
        //判断旧密码是否正确
        function (user, callbackInner) {
            if (user.userPassword != md5(input.oldPassword)) {
                var msg = {
                    "message": "原密码错误"
                };
                callbackInner(msg, null);
            } else {
                callbackInner(null, user);
            }

        },
        //用新密码替换旧密码
        function (user, callbackInner) {
            Users.update({_id: id}, {'userPassword': md5(input.newPassword)}, callbackInner);
        }
    ], callback);

};

exports.updateService = function (token, input, callback) {

    logger.info(input);

    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null)
        } else {
            var id = user._id;
            async.series([
                //更新用户的profile
                function (callbackInner) {
                    delete input.authenticationStatus;

                    if (input.nickName != null) {
                        //input.pinyin = pinyin(input.nickName, {style: pinyin.STYLE_NORMAL}).join('').toLowerCase();
                        //input.pinyinShort = pinyin(input.nickName, {style: pinyin.STYLE_FIRST_LETTER}).join('')
                        //input.pinyinSort = input.pinyin + '_' + (new Date()).getTime()
                    }

                    Users.update({_id: id}, input, callbackInner);
                },
                function (callbackInner) {
                    if (user.community != null) {
                        userCommunity.findOne({user: id, community: user.community._id}, function (err, result) {
                            if (result == null) {
                                var temp = new userCommunity();
                                temp.user = id;
                                temp.community = user.community._id;
                                if (input.roomUnit != null)
                                    temp.roomUnit = input.roomUnit;
                                if (input.roomNumber != null)
                                    temp.roomNumber = input.roomNumber;
                                temp.save(callbackInner)
                            } else {
                                var data = {};
                                if (input.roomUnit != null)
                                    data['roomUnit'] = input.roomUnit;
                                if (input.roomNumber != null)
                                    data['roomNumber'] = input.roomNumber;
                                userCommunity.update({user: id, community: user.community._id}, data, callbackInner)
                            }
                        })
                    } else {
                        callbackInner(null, null);
                    }
                },
                //更新最后修改日期
                function (callbackInner) {
                    Users.update({_id: id}, {dateLastModified: new Date()}, callbackInner);
                },
                function (callbackInner) {
                    if (input.userPortrait != null) {
                        userPortrait.findOne({_id: input.userPortrait}, 'hobby gender', function (err, result) {
                            Users.findOne({_id: id}, function (err, user) {
                                var flag = true;
                                if (user.hobbies != null) {
                                    user.hobbies.forEach(function (hobby) {
                                        hobby = hobby + '';
                                        if (hobby == result.hobby) {
                                            flag = false;
                                        }
                                    })
                                }
                                if (flag && result.hobby != null) {
                                    user.hobbies.push(result.hobby);
                                }
                                user.gender = result.gender;
                                user.save(callbackInner);
                            })
                        })
                    } else {
                        callbackInner(null, null);
                    }
                }
            ], callback);
        }
    });
};


/**
 * 上传用户头像，对图像始终是更新操作
 */
exports.setImagesToUser = function (id, images, callback) {
    Users.update({_id: id}, {$set: {'images': images}}, callback);
};


/**
 * 设置用户小区信息
 * @param community
 * @param callback
 */
exports.setUserCommunityService = function (token, community, callback) {
    Users.findOne({_id: toolUtil.getUserObjIdByToken(token)}, '_id community').populate('community', '_id communityName').exec(function (err, user) {
        if (user.community != null && user.community.communityName == community.name) {
            callback(null, user.community._id);
        } else {
            async.waterfall([
                function (callbackInner) {
                    if (user.community == null) {
                        callbackInner(null, null);
                    } else {
                        Community.findOne({_id: user.community._id}, 'chatGroupId', function (err, result) {
                            if (result != null && result.chatGroupId != null) {
                                toolUtil.getAndCacheHuanXinToken(function (err, token) {
                                    var args = {
                                        data: {},
                                        headers: {
                                            "Content-Type": "application/json",
                                            "Authorization": "Bearer " + token
                                        }
                                    };
                                    restClient.delete("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups/" + result.chatGroupId + "/users/" + user.huanxinUserName, args, function (data, response) {
                                        logger.info(data);
                                        if (response.statusCode == 200) {
                                            logger.info('Success to delete user from community group')
                                        }
                                    })
                                });
                            }
                            callbackInner(null, null);
                            redisClient.srem('u:c:' + user.community._id, user._id);
                        });
                    }
                },
                function (res, callbackInner) {
                    Community.findOne({communityName: community.name}, {}, function (err, result) {
                        callbackInner(null, result)
                    })
                },
                function (result, callbackInner) {
                    if (result == null) {
                        var temp = new Community();
                        temp.communityName = community.name;
                        temp.communityAddress = community.address;
                        temp.location.latitude = community.location.lat;
                        temp.location.longitude = community.location.lng;
                        temp.save();
                    }
                    callbackInner(null, null);
                },
                function (result, callbackInner) {
                    Community.findOne({communityName: community.name}, {}, function (err, result) {
                        userAuthentication.findOne({
                            user: user._id,
                            community: result._doc._id
                        }, 'status', function (err, re) {
                            if (re != null && re.status) {
                                Users.update({_id: user._id}, {'authenticationStatus': true}, callbackInner);
                            } else {
                                Users.update({_id: user._id}, {'authenticationStatus': false}, callbackInner);
                            }
                        });
                        callbackInner(null, result)
                    })
                },
                function (result, callbackInner) {
                    var temp = {
                        'community': result._doc._id
                    };
                    //userService.updateService(id,temp,callbackInner);
                    Users.update({_id: user._id}, temp, function (err, result) {
                        callbackInner(err, temp.community)
                    });

                    redisClient.sadd('u:c:' + temp.community, user._id);

                    if (result.chatGroupId == null) {
                        toolUtil.getAndCacheHuanXinToken(function (err, token) {
                            var args = {
                                data: {
                                    "groupname": result.communityName + '群聊大厅', //群组名称, 此属性为必须的
                                    "desc": result.communityName, //群组描述, 此属性为必须的
                                    "public": true, //是否是公开群, 此属性为必须的
                                    "maxusers": 2000, //群组成员最大数(包括群主), 值为数值类型,默认值200,此属性为可选的
                                    "approval": false, //加入公开群是否需要批准, 没有这个属性的话默认是true（不需要群主批准，直接加入）, 此属性为可选的
                                    "owner": '66customerService',//群组的管理员, 此属性为必须的
                                    "members": [user.huanxinUserName]
                                },
                                headers: {
                                    "Content-Type": "application/json",
                                    "Authorization": "Bearer " + token
                                }
                            };
                            restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups", args, function (data, response) {
                                if (response.statusCode == 200) {
                                    if (data.data.groupid != null) {
                                        result.chatGroupId = data.data.groupid;
                                        result.save();
                                    }
                                }
                            }).on('error', function (err) {
                                logger.error('create community chat group' + err.message);
                            });
                        });
                    } else {
                        toolUtil.getAndCacheHuanXinToken(function (err, token) {
                            var args = {
                                data: {},
                                headers: {
                                    "Content-Type": "application/json",
                                    "Authorization": "Bearer " + token
                                }
                            };
                            restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups/" + result.chatGroupId + "/users/" + user.huanxinUserName, args, function (data, response) {
                                if (response.statusCode == 200) {
                                    logger.info("Success to join community group");
                                }

                            }).on('error', function (err) {
                                logger.error('doRegisterService' + err.message);
                            });
                        });
                    }
                }
            ], callback)
        }
    })
};

/**
 * 设置用户小区     1.1.2
 * @param token
 * @param communityId
 * @param callback
 */
exports.setUserCommunityNewService = function (token, communityId, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (user == null) {
            callback(err, null);
        } else {
            var chatGroupId;

            if (user.community && user.community._id == communityId) {
                callback(null, null);
            } else {
                async.series([
                    function (callbackInner) {
                        Community.findOne({_id: communityId}, '_id chatGroupId', function (err, result) {
                            if (result == null) {
                                var msg = {
                                    message: '小区不存在'
                                };
                                callbackInner(msg, null)
                            } else {
                                chatGroupId = result.chatGroupId;
                                callbackInner(err, null);
                            }
                        });
                    },
                    function (callbackInner) {                                                    //更换小区
                        Users.update({_id: user._id}, {community: communityId}, callbackInner);
                        redisClient.sadd('u:c:' + communityId, user._id);
                    },
                    function (callbackInner) {                                                     //退群
                        if (user.community != null) {
                            Community.findOne({_id: user.community._id}, 'chatGroupId', function (err, result) {
                                if (result != null && result.chatGroupId != null && user.huanxinUserName != '66customerservice') {
                                    toolUtil.getAndCacheHuanXinToken(function (err, token) {
                                        var args = {
                                            data: {},
                                            headers: {
                                                "Content-Type": "application/json",
                                                "Authorization": "Bearer " + token
                                            }
                                        };
                                        restClient.delete("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups/" + result.chatGroupId + "/users/" + user.huanxinUserName, args, function (data, response) {
                                            logger.info(data);
                                            if (response.statusCode == 200) {
                                                logger.info('Success to delete user from community group')
                                            }
                                        })
                                    });
                                }
                                callbackInner(null, null);
                                redisClient.srem('u:c:' + user.community._id, user._id);
                            });
                        } else {
                            var temp = new userCommunity();
                            temp.user = user._id;
                            temp.community = communityId;
                            temp.save(callbackInner)
                        }
                    },
                    function (callbackInner) {
                        if (chatGroupId != null && user.huanxinUserName != '66customerservice') {
                            toolUtil.getAndCacheHuanXinToken(function (err, token) {
                                var args = {
                                    data: {},
                                    headers: {
                                        "Content-Type": "application/json",
                                        "Authorization": "Bearer " + token
                                    }
                                };
                                restClient.post("https://a1.easemob.com/66xiaoqu/" + huanxinEnv + "/chatgroups/" + chatGroupId + "/users/" + user.huanxinUserName, args, function (data, response) {
                                    if (response.statusCode == 200) {
                                        logger.info("Success to join community group");
                                    }

                                }).on('error', function (err) {
                                    logger.error('doRegisterService' + err.message);
                                });
                            });
                        }
                        callbackInner(null, null);
                    },
                    function (callbackInner) {
                        userAuthentication.findOne({
                            user: user._id,
                            community: communityId,
                            isValid: true
                        }, 'status', function (err, re) {
                            if (re != null && re.status) {
                                Users.update({_id: user._id}, {'authenticationStatus': true}, callbackInner);
                            } else {
                                Users.update({_id: user._id}, {'authenticationStatus': false}, callbackInner);
                            }
                        });
                    },
                    function (callbackInner) {
                        userCommunity.findOne({
                            user: user._id,
                            community: communityId
                        }, 'roomUnit roomNumber', function (err, result) {
                            var data = {};
                            if (result != null) {
                                if (result.roomUnit != null)
                                    data['roomUnit'] = result.roomUnit;
                                if (result.roomNumber != null)
                                    data['roomNumber'] = result.roomNumber;
                            }
                            Users.update({_id: user._id}, data, callbackInner)
                        })
                    }
                ], callback)
            }
        }
    });
};

/**
 * userService.js
 *根据用户名或邮箱或手机号查找用户ID
 *author：chenjinzhuan
 * */
exports.getUserIdService = function (username, callback) {
    async.series([
        //查找用户名中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({userName: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        },
        //查找email中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({email: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        },
        //查找手机号中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({mobilePhone: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        },
        //查找 wechatId 中是否存在给定的用户
        function (callbackInner) {
            Users.findOne({wechatId: username}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in getUserIdService...!');
                    return callbackInner(err);
                } else if (user == null) {
                    return callbackInner();
                } else {
                    return callbackInner(null, {userId: user._id});
                }
            });
        }
    ], function (err, results) {
        //仅仅返回结果数组中非空的元素
        async.series([
            function () {
                for (var i = 0; i < results.length; i++) {
                    if (results[i] != null) {
                        callback(null, results[i].userId);
                    }
                }
            }

        ], callback);

    });

};

/**
 * userService.js
 *获取通讯录
 * @param id
 * @param callback
 *author：chenjinzhuan
 * */
exports.getContactListService = function (id, callback) {
    Users.findOne({_id: id}, function (err, user) {
        if (err) {
            logger.error('Exception happened in getContactListService...!');
            return callback('err', null);
        } else if (user == null) {
            logger.error('user does not exist...!');
            return callback(err, null);
        } else {
            var contacts = [];
            var ids = user.contactBook;

            var ii = [];
            for (var i = 0; i < ids.length; i++) {
                ii[i] = i;
            }

            //对每一个id进行查找并处理
            async.forEachSeries(ii, function (i, callbackInner) {
                //需要populate某个属性时，必须将该属性添加到查找域中，如下的community
                Users.findOne({_id: ids[i]}, '_id nickName community huanxinUserName images')
                    .populate('community', 'communityName')
                    .exec(function (err, contact) {

                        if (err) {
                            logger.error('Exception happened in getContactListService......!');
                            return callbackInner(err, null);
                        } else if (contact == null) {
                            logger.error('Exception happened in getContactListService11......!');
                            return callbackInner(err, null);
                        } else {
                            var elem = {
                                objId: null,
                                nickName: null,
                                communityName: null,
                                huanxinUserName: null,
                                images: null
                            };
                            elem.objId = contact._id;
                            elem.nickName = contact.nickName;
                            elem.communityName = contact.communityName;
                            elem.huanxinUserName = contact.huanxinUserName;
                            elem.images = contact.images;
                            contacts[i] = elem;
                            //contacts = contact;
                            callbackInner();
                        }
                    });
            }, function () {
                return callback(null, contacts);
            });
        }
    });
};

/**
 * userService.js
 *添加到通讯录
 *author：chenjinzhuan
 * */
exports.addToContactListService = function (id, userName, userNameToAdd, callback) {
    //由于环信在当前用户添加好友时，在好友的好友列表中也会添加当前用户。所以为了和环信同步，需要在数据库中也相互添加好友
    async.waterfall([
        //通过好友用户名获取好友用户Id
        function (callbackInner) {
            userService.getUserIdService(userNameToAdd, function (err, idToAdd) {
                if (err) {
                    logger.debug('Exception happened in addToContactListService 1....');
                    return callback(err);
                } else {
                    logger.debug('succeed to get the idToAdd...');
                    callbackInner(null, idToAdd);
                }
            });
        },
        //对当前用户添加好友
        function (idToAdd, callbackInner) {
            //根据用户id查找用户信息
            Users.findOne({_id: id}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in addToContactListService...!');
                    return callback(err);
                } else if (user == null) {
                    logger.error('addToContactListService: User does not exist...!');
                    return callback(err, null);
                } else {
                    logger.debug('user:' + user.contactBook);
                    //判断要添加的用户是否存在
                    for (var i = 0; i < user.contactBook.length; i++) {
                        if (idToAdd.toString() == user.contactBook[i]) {
                            logger.error('addToContactListService: User already exist...!');
                            return callback(err, null);
                        }
                    }

                    //给当前用户添加好友
                    user.contactBook.push(idToAdd);
                    user.save(function (err) {
                        if (err) {
                            logger.debug('Exception happened in addToContactListService 2....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 1...');
                            callbackInner(null, idToAdd);
                        }
                    });
                }
            });
        },
        //对好友添加当前用户
        function (idToAdd, callbackInner) {
            //根据好友id查找用户
            Users.findOne({_id: idToAdd}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in addToContactListService...!');
                    return callback(err);
                } else if (user == null) {
                    logger.error('addToContactListService: User does not exist...!');
                    return callback(err, null);
                } else {
                    //判断要添加的用户是否存在
                    for (var i = 0; i < user.contactBook.length; i++) {
                        if (id.toString() == user.contactBook[i]) {
                            logger.error('addToContactListService: User already exist...!');
                            return callback(err, null);
                        }
                    }

                    //对好友添加当前用户
                    var mongoose = require('mongoose');
                    var objId = mongoose.Types.ObjectId(id);
                    //var objId = mongoose.mongo.BSONPure.ObjectID.fromString(id);
                    user.contactBook.push(objId);
                    Users.update({_id: idToAdd}, {contactBook: user.contactBook}, function (err) {
                        if (err) {
                            logger.debug('Exception happened in addToContactListService 3....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 2...');
                            callbackInner(null, idToAdd);
                        }
                    });
                    //user.save(function (err) {
                    //    if (err) {
                    //        logger.debug('Exception happened in addToContactListService 3....');
                    //        return callback(err);
                    //    } else {
                    //        logger.debug('succeed to save the user 2...');
                    //        callbackInner(null, idToAdd);
                    //    }
                    //});
                }
            });
        },
        //在环信中添加好友
        function (callbackInner) {
            //环信添加好友开始
            var http = require('http');

            //获取环信token
            userService.getHuanxinTokenService(function (err, results) {
                if (err) {
                    logger.error('Exception happened when add to contactList 1...!');
                } else {
                    logger.debug('Set Token...!');
                    //var resultsParse = JSON.parse(results);
                    //var resultsParse = results;

                    //构造链接选项
                    var urlOpts = {
                        host: 'a1.easemob.com',
                        //path: '/easemob-demo/chatdemoui/users/'+userName+'/contacts/users/'+userNameToAdd,
                        path: '/66xiaoqu/' + huanxinEnv + '/users/' + userName + '/contacts/users/' + userNameToAdd,
                        port: '80',
                        method: 'POST',
                        headers: {
                            "Authorization": 'Bearer ' + results
                        }
                    };

                    //向环信提交请求
                    var request = http.request(urlOpts, function (response) {
                        response.on('data', function (chunk) {//请求成功的情况
                            logger.debug(chunk.toString());
                            return callback(null);
                        });
                    }).on('error', function (e) {//请求失败的情况
                        logger.debug('error:' + e.stack);
                        //删除在数据库通讯录中的用户好友
                        userService.RemoveFromContactListService(id, userName, userNameToAdd, function (err) {
                            if (err) {
                                logger.error(err.message);
                                logger.error('Exception happened when Remove to contactList in addToContactList...!');
                                return callback(err);
                            } else {
                                logger.debug('Remove to contactlist successfully in addToContactList...!');
                                return callback(err);
                            }
                        });
                    });
                    // write data to request body
                    //request.write(post_data + "\n");
                    request.end();
                }
            });

            //环信添加好友结束
        }
    ], callback);


};

/**
 * userService.js
 *从通讯录删除
 *author：chenjinzhuan
 * */
exports.RemoveFromContactListService = function (id, userName, userNameToRemove, callback) {
    //由于环信在当前用户删除好友时，在好友的好友列表中也会删除当前用户。所以为了和环信同步，需要在数据库中也相互删除好友
    async.waterfall([
        //通过好友用户名获取好友用户Id
        function (callbackInner) {
            userService.getUserIdService(userNameToRemove, function (err, idToRemove) {
                if (err) {
                    logger.debug('Exception happened in RemoveFromContactListService 1....');
                    return callback(err);
                } else {
                    logger.debug('succeed to get the idToAdd...');
                    callbackInner(null, idToRemove);
                }
            });
        },
        //对当前用户删除好友
        function (idToRemove, callbackInner) {
            //根据用户id查找用户信息
            Users.findOne({_id: id}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in RemoveFromContactListService 2...!');
                } else if (user == null) {
                    logger.error('RemoveFromContactListService: User does not exist...!');
                    return callback(err);
                } else {
                    logger.debug('contactbook hello1:' + user.contactBook);
                    logger.debug('contactbook hello1:' + toString(user.contactBook[0]));
                    logger.debug('contactbook hello1:' + user.contactBook[1]);
                    logger.debug('contactbook hello1:' + user);
                    logger.debug('contactbook idtoremove:' + idToRemove);

                    for (var i = user.contactBook.length; i >= 0; i--) {
                        //if (/*idToRemove ==*/'54992018af970c5432de1b05' == user.contactBook[i]) {
                        if (idToRemove.toString() == user.contactBook[i]) {
                            user.contactBook.splice(i, 1);
                            logger.debug('contactbook:' + i + '...' + user.contactBook);
                        }
                    }
                    logger.debug('contactbook hello2:' + user.contactBook);

                    user.save(function (err) {
                        if (err) {
                            logger.debug('Exception happened in RemoveFromContactListService 3....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 1...');
                            callbackInner(null, idToRemove);
                        }
                    });
                }
            });
        },
        //对好友删除当前用户
        function (idToRemove, callbackInner) {
            //根据好友id查找用户
            Users.findOne({_id: idToRemove}, function (err, user) {
                if (err) {
                    logger.error('Exception happened in RemoveFromContactListService 1...!');
                } else if (user == null) {
                    logger.error('RemoveFromContactListService: User does not exist...!');
                    return callback(err);
                } else {
                    logger.debug('contactbook hello1:' + user.contactBook);
                    logger.debug('contactbook hello1:' + toString(user.contactBook[0]));
                    logger.debug('contactbook hello1:' + user.contactBook[1]);
                    logger.debug('contactbook hello1:' + user);
                    logger.debug('contactbook idtoremove:' + idToRemove);

                    for (var i = user.contactBook.length; i >= 0; i--) {
                        //if (/*idToRemove ==*/'54992018af970c5432de1b05' == user.contactBook[i]) {
                        if (id.toString() == user.contactBook[i]) {
                            user.contactBook.splice(i, 1);
                            logger.debug('contactbook:' + i + '...' + user.contactBook);
                        }
                    }
                    logger.debug('contactbook hello2:' + user.contactBook);
                    Users.update({_id: idToRemove}, {contactBook: user.contactBook}, function (err) {
                        if (err) {
                            logger.debug('Exception happened in addToContactListService 3....');
                            return callback(err);
                        } else {
                            logger.debug('succeed to save the user 2...');
                            callbackInner(null, idToRemove);
                        }
                    });
                    //user.save(function (err) {
                    //    if (err) {
                    //        logger.debug('Exception happened in RemoveFromContactListService 4....');
                    //        return callback(err);
                    //    } else {
                    //        logger.debug('succeed to save the user 2...');
                    //        callbackInner(null, idToRemove);
                    //    }
                    //});

                }
            });
        },
        //在环信中删除好友
        function (callbackInner) {
            //环信删除好友开始
            var http = require('http');

            //获取环信token
            userService.getHuanxinTokenService(function (err, results) {
                if (err) {
                    logger.error('Exception happened when remove contactList 1...!');
                    res.json(messageUtil.composeFailedMessage('Exception happened when remove contactList 5...!'));
                } else {
                    logger.debug('Set Token...!');
                    //var resultsParse = JSON.parse(results);
                    //var resultsParse = results;
                    logger.debug('results1: ' + results);
                    logger.debug('results: ' + results);

                    //构造链接选项
                    var urlOpts = {
                        host: 'a1.easemob.com',
                        //path: '/easemob-demo/chatdemoui/users/'+userName+'/contacts/users/'+userNameToAdd,
                        path: '/66xiaoqu/' + huanxinEnv + '/users/' + userNameToRemove + '/contacts/users/' + userName,
                        port: '80',
                        method: 'DELETE',
                        headers: {
                            "Authorization": 'Bearer ' + results
                        }
                    };

                    //向环信提交请求
                    var request = http.request(urlOpts, function (response) {
                        response.on('data', function (chunk) {//请求成功的情况
                            logger.debug(chunk.toString());
                            return callback(null);
                        });
                    }).on('error', function (e) {//请求失败的情况
                        logger.debug('error:' + e.stack);
                        //添加已经删除的数据库中的好友
                        userService.addToContactListService(id, idToRemove, function (err) {
                            if (err) {
                                logger.debug(err.message);
                                logger.error('Exception happened when add to contactList in RemoveFromContactList...!');
                                return callback(err);
                            } else {
                                logger.debug('Add to contactlist successfully in RemoveFromContactList...!');
                                return callback(err);
                            }
                        });
                    });
                    // write data to request body
                    //request.write(post_data + "\n");
                    request.end();
                }
            });

            //环信删除好友结束
        }
    ], callback);


};

/**
 * 关注
 */
exports.followupService = function (category, token, id, callback) {
    var userId = toolUtil.getUserObjIdByToken(token);

    if (category == 'question') {
        UserFollowups.findOne({'user': userId, 'question': id}).exec(function (err, result) {
            if (result == null) {
                var temp = new UserFollowups();
                temp.category = category;
                temp.user = toolUtil.getUserObjIdByToken(token);
                temp.question = id;
                temp.save(callback);
            } else {
                var msg = {
                    "message": 'The question has been followup'
                };
                callback(msg, null);
            }
        })
    } else if (category == 'activity') {
        UserFollowups.findOne({'user': userId, 'activity': id}).exec(function (err, result) {
            if (result == null) {
                var temp = new UserFollowups();
                temp.category = category;
                temp.user = toolUtil.getUserObjIdByToken(token);
                temp.activity = id;
                temp.save(callback);
            } else {
                var msg = {
                    "message": 'The activity has been followup'
                };
                callback(msg, null);
            }
        })
    } else if (category == 'user') {
        UserFollowups.findOne({'user': userId, 'followUser': id}).exec(function (err, result) {
            if (result == null) {
                var temp = new UserFollowups();
                temp.category = category;
                temp.user = toolUtil.getUserObjIdByToken(token);
                temp.followUser = id;
                temp.save(callback);
            } else {
                var msg = {
                    "message": 'This user has been followup'
                };
                callback(msg, null);
            }
        })
    } else {
        var msg = {
            "message": 'No such category '
        };
        callback(msg, null);
    }

};

/**
 * 取消关注
 */
exports.cancelFollowupService = function (category, token, id, callback) {
    if (category == 'question') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'question': id}).exec(callback);
    } else if (category == 'activity') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'activity': id}).exec(callback);
    } else if (category == 'user') {
        UserFollowups.remove({'user': toolUtil.getUserObjIdByToken(token), 'followUser': id}).exec(callback);
    }
};

/**
 * 获取某类关注清单
 */
exports.getFollowupListService = function (page, category, token, callback) {
    var index = Number(page) * listPageSize;
    async.waterfall([
        function (callbackInner) {
            UserFollowups.find({
                'category': category,
                'user': toolUtil.getUserObjIdByToken(token)
            }, 'category question activity dateCreated').sort('-dateCreated').skip(index).limit(listPageSize).exec(function (err, results) {
                callbackInner(null, results);
            })
        },
        function (results, callbackInner) {
            if (results == undefined) {
                callbackInner(null, null);
            } else {
                var questionIdArray = new Array(results.length);

                for (var i = 0; i < results.length; i++) {
                    questionIdArray[i] = results[i].question;
                }

                var data = [];
                async.eachSeries(questionIdArray, function (id, callback) {
                    Question.findOne({
                        _id: id,
                        'isValid': true
                    }, '_id desc community replies.replyStatus replies._id replies.replyDesc replies.images.imageURL replies.images._id replies.dateReplied replies.repliedBy browserCount category status tag images.imageURL images._id replies pollOptions pollUserList dateCreated createdBy')
                        .populate('replies.repliedBy', '_id nickName images')
                        .populate('community', '_id communityName').populate('createdBy', '_id nickName images').populate('tag', 'category value _id').exec(function (err, question) {
                            if (question != null) {
                                if (question.category == 'poll') {
                                    var pollList = question.pollUserList;
                                    if (pollList != null && pollList.indexOf(toolUtil.getUserObjIdByToken(token)) != -1) {
                                        question._doc['voted'] = 'Yes'
                                    } else {
                                        question._doc['voted'] = 'No'
                                    }
                                    if (pollList != null) {
                                        question._doc['numberOfReplies'] = pollList.length;
                                    }

                                    question.browserCount = undefined;
                                } else {
                                    if (question.replies != null) {
                                        question._doc['numberOfReplies'] = question.replies.length;

                                        question.replies.forEach(function (reply) {
                                            if (reply.replyStatus == '已采纳') {
                                                question._doc['adoptedReply'] = reply;
                                            }
                                        })
                                    }

                                    if (question.browserCount == null) {
                                        question.browserCount = 0;
                                    }
                                    if (question.browserCount >= 200) {
                                        question._doc['hot'] = true;
                                    } else {
                                        question._doc['hot'] = false;
                                    }
                                }
                                if (question._doc.tag == null || question._doc.tag.length == 0) {
                                    question._doc.tag = undefined;
                                }
                                question._doc.replies = undefined;
                                question._doc.pollUserList = undefined;

                                data.push(question);
                            }
                            callback();
                        });
                }, function (err, results) {
                    if (err) {
                        var msg = {
                            "message": "get err"
                        };
                        callback(msg, null);
                    } else {
                        callback(null, data);
                    }
                });
            }
        }
    ], callback)
};

exports.getFollowupUsersService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            UserFollowups.find({
                'category': 'user',
                'user': user._id
            }, 'followUser dateCreated').sort('-dateCreated').exec(function (err, results) {
                var data = [];
                if (results != null) {
                    async.eachSeries(results, function (result, callback) {
                        Users.findOne({
                            _id: result.followUser,
                            community: user.community._id
                        }, '_id nickName images userType userPortrait authenticationStatus').populate('userPortrait', '_id value portraitURL')
                            .exec(function (err, user) {
                                if (user != null) {
                                    data.push(user);
                                }
                                callback();
                            })
                    }, function (err) {
                        callback(err, data);
                    })
                } else {
                    callback(err, null);
                }
            });
        }
    });
};

/**
 * 获取邻居列表
 */
exports.getNeighbourListService = function (page, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {

            var index = Number(page) * listPageSize;
            var communityId = user.community._id;
            var userId = user._id;
            Users.find({
                'community': communityId,
                '_id': {'$ne': userId},
                'messagePushSetting.showMeNearOn': true
            }, '_id nickName images huanxinUserName').skip(index).limit(listPageSize).exec(callback);
        }
    });
};

exports.findUserService = function (id, callback) {
    Users.findOne({$or: [{userName: id}, {email: id}, {mobilePhone: id}]}, callback);
};

exports.getUserProfileService = function (userId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            async.series([
                function (callbackInner) {
                    Users.findOne({_id: userId}, 'huanxinUserName community userType', function (err, result) {
                        if (user.community._id != result.community && result.userType != 'service') {
                            var msg = {
                                "message": "不在同一个小区，无法查看资料"
                            };
                            callbackInner(msg, null);
                        } else {
                            callbackInner(err, result);
                        }
                    })
                },
                function (callbackInner) {
                    Users.findOne({_id: userId}, 'birthDate nickName images age huanxinUserName gender maritalStatus hasChildren apartmentDetail hobbies community homeTown.country homeTown.province homeTown.city homeTown.county userType speciality userPortrait school authenticationStatus job roomUnit showUnit')
                        .populate('community', '_id communityName communityAddress').populate('userPortrait', 'portraitURL value')
                        .populate('homeTown.country', '_id name').populate('homeTown.province', '_id name')
                        .populate('homeTown.city', '_id name').populate('homeTown.county', '_id name')
                        .populate('hobbies', '_id value').exec(function (err, result) {
                            if (result.showUnit != null && !result.showUnit) {
                                result.roomUnit = undefined;
                            }
                            if (result.community == null) {
                                result.community = undefined;
                            }
                            result.showUnit = undefined;
                            callbackInner(err, result);
                        });
                },
                function (callbackInner) {

                    //Question.find({
                    //    $or: [{
                    //        'createdBy': userId,
                    //        'category': 'question',
                    //        'isValid': true
                    //    }, {
                    //        'replies.repliedBy': userId,
                    //        'category': 'question',
                    //        'isValid': true
                    //    }]
                    //}, '_id desc community replies.replyStatus replies._id replies.replyDesc replies.images.imageURL replies.images._id replies.dateReplied replies.repliedBy browserCount category tag images replies dateCreated createdBy')
                    //    .skip(0).limit(20).populate('tag', 'category value _id')
                    //    .populate('replies.repliedBy', '_id nickName images')
                    //    .populate('community', '_id communityName').populate('createdBy', '_id nickName images').sort('-dateCreated').exec(function (err, results) {
                    //        if (results == undefined || results == null) {
                    //            var msg = {
                    //                "message": 'get err'
                    //            };
                    //            callback(msg, null);
                    //        } else {
                    //            results.forEach(function (question) {
                    //                if (question.replies != null) {
                    //                    question._doc['numberOfReplies'] = question.replies.length;
                    //
                    //                    question.replies.forEach(function (reply) {
                    //                        if (reply.replyStatus == '已采纳') {
                    //                            question._doc['adoptedReply'] = reply;
                    //                        }
                    //                    });
                    //
                    //                    if (question._doc.adoptedReply == undefined && userId != question.createdBy._id) {
                    //                        question.replies.forEach(function (reply) {
                    //                            if (userId == reply.repliedBy._id) {
                    //                                question._doc['myReply'] = reply;
                    //                            }
                    //                        });
                    //                    }
                    //                }
                    //                if (question.browserCount == null) {
                    //                    question.browserCount = 0;
                    //                }
                    //
                    //                if (question._doc.tag == null || question._doc.tag.length == 0) {
                    //                    question._doc.tag = undefined;
                    //                }
                    //                question._doc.replies = undefined;
                    //            });
                    //            callbackInner(null, results);
                    //        }
                    //    })

                    var data = [];
                    callbackInner(null, data);
                },
                function (callbackInner) {
                    UserFollowups.findOne({'user': user._id, 'followUser': userId}, '', function (err, result) {
                        if (result == null) {
                            callbackInner(err, 'No');
                        } else {
                            callbackInner(err, 'Yes');
                        }
                    })
                }
                //function (callbackInner) {
                //    UserFollowups.find({
                //        'category': 'activity',
                //        'user': userId
                //    }, 'category question activity dateCreated', function (err, results) {
                //        var activityIdArray = new Array();
                //        if (results == undefined) {
                //        } else {
                //            for (var i = 0; i < results.length; i++) {
                //                activityIdArray[i] = results[i].activity;
                //            }
                //        }
                //
                //        Activity.find({$or: [{'createdBy': userId}, {_id: {$in: activityIdArray}}]}, '_id images activityName startDateTime endDateTime createdBy')
                //            .sort('-startDateTime').limit(2).exec(function (err, results) {
                //                if (results != null) {
                //                    results.forEach(function (activity) {
                //                        var start = moment(activity.startDateTime).format('MM月DD日 HH:mm');
                //                        var end = moment(activity.endDateTime).format('MM月DD日 HH:mm');
                //                        activity._doc['time'] = start + '—' + end;
                //
                //                        activity.startDateTime = undefined;
                //                        activity.endDateTime = undefined;
                //                    })
                //                }
                //                callbackInner(err, results);
                //            })
                //    })
                //}
            ], callback)
        }
    });
};

/**
 * 获取个人问题列表
 * @param page
 * @param userId
 * @param token
 * @param callback
 */
exports.getUserQuestionListService = function (page, userId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            var index = Number(page) * listPageSize;

            Question.find({
                $or: [{
                    'createdBy': userId,
                    community: user.community._id,
                    'isValid': true
                }, {
                    'createdBy': {'$ne': userId},
                    'replies.repliedBy': userId,
                    community: user.community._id,
                    'isValid': true
                }]
            }, '_id desc community replies.replyStatus replies._id replies.replyDesc replies.images.imageURL replies.images._id replies.dateReplied replies.repliedBy browserCount category tag images replies dateCreated createdBy').skip(index).limit(listPageSize)
                .populate('tag', 'category value _id')
                .populate('replies.repliedBy', '_id nickName images')
                .populate('community', '_id communityName').populate('createdBy', '_id nickName images').sort('-dateCreated')
                .exec(function (err, results) {
                    if (results == undefined || results == null) {
                        var msg = {
                            "message": 'get err'
                        };
                        callback(msg, null);
                    } else {
                        results.forEach(function (question) {
                            if (question.replies != null) {
                                question._doc['numberOfReplies'] = question.replies.length;

                                question.replies.forEach(function (reply) {
                                    if (reply.replyStatus == '已采纳' && userId == question.createdBy._id) {
                                        question._doc['adoptedReply'] = reply;
                                    }
                                });

                                if (question._doc.adoptedReply == undefined && question.createdBy != null && userId != question.createdBy._id) {
                                    question.replies.forEach(function (reply) {
                                        if (userId == reply.repliedBy._id) {
                                            question._doc['myReply'] = reply;
                                        }
                                    });
                                }
                            }
                            if (question.browserCount == null) {
                                question.browserCount = 0;
                            }

                            if (question._doc.tag == null || question._doc.tag.length == 0) {
                                question._doc.tag = undefined;
                            }
                            question._doc.replies = undefined;
                        });
                        callback(null, results);
                    }
                });
        }
    });
};

exports.getUserQuestionListNewService = function (page, userId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null)
        } else {
            page = Number(page);
            var data = [];

            async.series([
                function (callbackInner) {
                    ugcIndex.find({community: user.community._id, createdBy: userId}).sort({
                        dateCreated: -1
                    }).exec(function (err, result) {
                        if (result != null) {

                            async.each(result, function (ugc, callbackInner) {
                                if (ugc.category == 'neighbourActivity') {
                                    neighbourActivity.findOne({_id: ugc.ugcId}, '_id title replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy desc category dateCreated createdBy')
                                        .populate('tag', 'category value _id')
                                        .populate('replies.repliedBy', '_id nickName images')
                                        .populate('createdBy', '_id nickName images')
                                        .exec(function (err, activity) {
                                            if (activity != null) {

                                                if (activity.replies != null) {
                                                    activity._doc['numberOfReplies'] = activity.replies.length;
                                                    activity.replies.forEach(function (reply) {
                                                        if (reply.replyStatus == '已采纳') {
                                                            activity._doc['adoptedReply'] = reply;
                                                        }
                                                    });
                                                }
                                                activity._doc.replies = undefined;
                                                data.push(activity);
                                            }
                                            callbackInner(err);
                                        })
                                } else {
                                    Question.findOne({
                                        _id: ugc.ugcId,
                                        'isValid': true
                                    }, '_id desc replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy category replies dateCreated createdBy')
                                        .populate('replies.repliedBy', '_id nickName images')
                                        .populate('createdBy', '_id nickName images').exec(function (err, question) {
                                            if (question != null) {
                                                if (question.replies != null) {
                                                    question._doc['numberOfReplies'] = question.replies.length;
                                                    question.replies.forEach(function (reply) {
                                                        if (reply.replyStatus == '已采纳') {
                                                            question._doc['adoptedReply'] = reply;
                                                        }
                                                    });
                                                }
                                                question._doc.replies = undefined;

                                                if (question._doc.adoptedReply != null && question._doc.adoptedReply.replyDesc.indexOf(atFlag) != -1) {
                                                    replyAt.findOne({replyId: question._doc.adoptedReply._id + ''}, function (err, at) {
                                                        if (at != null && at.uList != null) {
                                                            at.uList.forEach(function (temp, i) {
                                                                question._doc.adoptedReply.replyDesc = question._doc.adoptedReply.replyDesc.replace(new RegExp("@\\{" + i + "\\}"), '@' + temp.nickName + ' ')
                                                            });
                                                        }
                                                        data.push(question);
                                                        callbackInner()
                                                    }).populate('uList', '_id nickName');
                                                } else {
                                                    data.push(question);
                                                    callbackInner(err);
                                                }
                                            } else {
                                                callbackInner();
                                            }
                                        })
                                }
                            }, function (err) {
                                callbackInner(err, data);
                            })
                        } else {
                            callbackInner(err, data);
                        }
                    });
                },
                function (callbackInner) {
                    ugcReply.find({
                        //$or: [{
                        //    'createdBy': userId,
                        //    community: user.community._id
                        //}, {
                        'createdBy': {'$ne': userId},
                        'repliedBy': userId,
                        ugcReply: {$not: {$size: 0}},
                        community: user.community._id
                        //}]
                    }).sort('-dateCreated').exec(function (err, result) {
                        if (result != null) {
                            async.each(result, function (ugc, callbackInner) {
                                if (ugc.category == 'neighbourActivity') {
                                    neighbourActivity.findOne({_id: ugc.ugcId}, '_id title replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy desc category dateCreated createdBy')
                                        .populate('tag', 'category value _id')
                                        .populate('replies.repliedBy', '_id nickName images')
                                        .populate('createdBy', '_id nickName images')
                                        .exec(function (err, activity) {
                                            if (activity != null) {
                                                if (activity.replies != null) {
                                                    activity._doc['numberOfReplies'] = activity.replies.length;
                                                    activity.replies.forEach(function (reply) {
                                                        if (reply.replyStatus == '已采纳') {
                                                            activity._doc['adoptedReply'] = reply;
                                                        }
                                                    });
                                                }
                                                if (activity._doc.adoptedReply == undefined && activity.createdBy != null && userId != activity.createdBy._id) {
                                                    activity.replies.forEach(function (reply) {
                                                        if (userId == reply.repliedBy._id) {
                                                            activity._doc['myReply'] = reply;
                                                        }
                                                    });
                                                }

                                                activity._doc.replies = undefined;


                                                if (activity._doc.myReply != null && activity._doc.myReply.replyDesc.indexOf(atFlag) != -1) {
                                                    replyAt.findOne({replyId: activity._doc.myReply._id + ''}, function (err, at) {
                                                        if (at != null && at.uList != null) {
                                                            at.uList.forEach(function (temp, i) {
                                                                activity._doc.myReply.replyDesc = activity._doc.myReply.replyDesc.replace(new RegExp("@\\{" + i + "\\}"), '@' + temp.nickName + ' ')
                                                            });
                                                        }
                                                        data.push(activity);
                                                        callbackInner()
                                                    }).populate('uList', '_id nickName');
                                                } else {
                                                    data.push(activity);
                                                    callbackInner(err);
                                                }
                                            } else {
                                                callbackInner(err);
                                            }
                                        })
                                } else {
                                    Question.findOne({
                                        _id: ugc.ugcId,
                                        'isValid': true
                                    }, '_id desc replies.replyStatus replies._id replies.replyDesc  replies.dateReplied replies.repliedBy category replies dateCreated createdBy')
                                        .populate('replies.repliedBy', '_id nickName images')
                                        .populate('createdBy', '_id nickName images').exec(function (err, question) {
                                            if (question != null) {
                                                if (question.replies != null) {
                                                    question._doc['numberOfReplies'] = question.replies.length;
                                                    question.replies.forEach(function (reply) {
                                                        if (reply.replyStatus == '已采纳' && userId == question.createdBy._id) {
                                                            question._doc['adoptedReply'] = reply;
                                                        }
                                                    });

                                                    if (question._doc.adoptedReply == undefined && question.createdBy != null && userId != question.createdBy._id) {
                                                        question.replies.forEach(function (reply) {
                                                            if (userId == reply.repliedBy._id) {
                                                                question._doc['myReply'] = reply;
                                                            }
                                                        });
                                                    }
                                                }

                                                question._doc.replies = undefined;

                                                if (question._doc.myReply != null && question._doc.myReply.replyDesc.indexOf(atFlag) != -1) {
                                                    replyAt.findOne({replyId: question._doc.myReply._id + ''}, function (err, at) {
                                                        if (at != null && at.uList != null) {
                                                            at.uList.forEach(function (temp, i) {
                                                                question._doc.myReply.replyDesc = question._doc.myReply.replyDesc.replace(new RegExp("@\\{" + i + "\\}"), '@' + temp.nickName + ' ')
                                                            });
                                                        }
                                                        data.push(question);
                                                        callbackInner()
                                                    }).populate('uList', '_id nickName');
                                                } else {
                                                    data.push(question);
                                                    callbackInner(err);
                                                }
                                            } else {
                                                callbackInner();
                                            }
                                        })
                                }
                            }, function (err) {
                                callbackInner(err, data);
                            })
                        } else {
                            callbackInner(null, []);
                        }
                    });
                }
            ], function (err, result) {
                data.sort(function (a, b) {
                    return b.dateCreated - a.dateCreated;
                });
                var re = data.slice(page * listPageSize, (page + 1) * listPageSize);
                callback(err, re);
            });
        }
    })
};

/**
 * 首页数据service
 * @param token
 * @param callback
 */
exports.getHomePageService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            async.series([                       //modules
                function (callbackInner) {
                    appHomeModules.find({}, '-_id title imageURL displayOrder fieldName').sort('displayOrder').exec(callbackInner);
                },
                function (callbackInner) {       //new
                    var data = [];
                    freshNews.find({'community': user.community._id}, 'tag openType title bgColor url newsId createdBy').sort('-displayOrder').limit(3).exec(function (err, results) {
                        if (results != null && results.length > 0) {
                            results.forEach(function (news) {
                                var temp = {
                                    "tag": news.tag,
                                    "openType": news.openType,
                                    "type": news.tag,
                                    "bgColor": news.bgColor,
                                    "newsId": news.newsId,
                                    "createdBy": news.createdBy,
                                    "message": news.title,
                                    "url": news.url
                                };
                                data.push(temp);
                            })
                        }
                        callbackInner(err, data);
                    });


                    //var data = new Array();
                    //
                    //async.series([
                    //    function (callbackInner) {
                    //        Bulletins.findOne({
                    //            community: user.community._id,
                    //            isFresh: true
                    //        }, '_id title', function (err, result) {
                    //            if (result != null) {
                    //                var temp = {
                    //                    "tag": "公告",
                    //                    "openType": 1,
                    //                    "type": "公告",
                    //                    "bgColor": "#F7744A",
                    //                    "message": result.title,
                    //                    "newsId": result._id
                    //                };
                    //                data.push(temp);
                    //                callbackInner(err, null);
                    //            } else {
                    //                Bulletins.find({'community': user.community._id}, '_id title').sort('-dateCreated').limit(1).exec(function (err, results) {
                    //                    if (results != null && results.length > 0) {
                    //                        var result = results[0];
                    //                        var temp = {
                    //                            "openType": 1,
                    //                            "tag": "公告",
                    //                            "type": "公告",
                    //                            "bgColor": "#F7744A",
                    //                            "message": result.title,
                    //                            "newsId": result._id
                    //                        };
                    //                        data.push(temp);
                    //                    }
                    //                    callbackInner(err, null);
                    //                })
                    //            }
                    //        });
                    //    },
                    //    function (callbackInner) {
                    //        var date = (new Date).getTime() - 3 * 24 * 60 * 60 * 1000;
                    //        Users.find({
                    //            dateCreated: {$gte: new Date(date)},
                    //            'community': user.community._id,
                    //            authenticationStatus: true,
                    //            nickName: {$ne: '小6客服'}
                    //        }, '_id images nickName authenticationStatus userType').exec(function (err, results) {
                    //            if (results != null && results.length > 0) {
                    //                var num = toolUtil.getRandomNumArray(1, results.length);
                    //
                    //                var newUser = results[num[0]];
                    //                if (newUser.images != null && newUser.images.length > 0) {
                    //                    var temp = {
                    //                        "openType": 2,
                    //                        "tag": "新人",
                    //                        "type": "新人",
                    //                        "bgColor": "#FFCC00",
                    //                        "newsId": newUser._id,
                    //                        "message": newUser.nickName,
                    //                        "imageURL": newUser.images[0].imageURL
                    //                    };
                    //                    data.push(temp);
                    //
                    //                } else {
                    //                    var temp = {
                    //                        "openType": 2,
                    //                        "tag": "新人",
                    //                        "type": "新人",
                    //                        "bgColor": "#FFCC00",
                    //                        "newsId": newUser._id,
                    //                        "message": newUser.nickName
                    //                    };
                    //                    data.push(temp);
                    //                }
                    //                callbackInner(err, null);
                    //            } else {
                    //                Users.find({
                    //                    'community': user.community._id,
                    //                    authenticationStatus: true,
                    //                    nickName: {$ne: null}
                    //                }, '_id images nickName authenticationStatus userType').sort('-dateCreated').limit(20).exec(function (err, results) {
                    //                    if (results != null && results.length > 0) {
                    //
                    //                        var num = toolUtil.getRandomNumArray(1, results.length);
                    //                        var newUser = results[num[0]];
                    //                        if (newUser.images != null && newUser.images.length > 0) {
                    //                            var temp = {
                    //                                "openType": 2,
                    //                                "tag": "新人",
                    //                                "type": "新人",
                    //                                "bgColor": "#FFCC00",
                    //                                "newsId": newUser._id,
                    //                                "message": newUser.nickName,
                    //                                "imageURL": newUser.images[0].imageURL
                    //                            };
                    //                            data.push(temp);
                    //
                    //                        } else {
                    //                            var temp = {
                    //                                "openType": 2,
                    //                                "tag": "新人",
                    //                                "type": "新人",
                    //                                "bgColor": "#FFCC00",
                    //                                "newsId": newUser._id,
                    //                                "message": newUser.nickName
                    //                            };
                    //                            data.push(temp);
                    //                        }
                    //                    }
                    //                    callbackInner(err, null);
                    //                });
                    //            }
                    //        });
                    //    },
                    //    function (callbackInner) {
                    //        freshNews.find({'community': user.community._id}, 'tag openType title url newsId createdBy').sort('-dateCreated').limit(1).exec(function (err, results) {
                    //            if (results != null && results.length > 0) {
                    //                var news = results[0];
                    //                var temp = {
                    //                    "tag": news.tag,
                    //                    "openType": news.openType,
                    //                    "type": news.tag,
                    //                    "bgColor": "#7DB2EC",
                    //                    "newsId": news.newsId,
                    //                    "createdBy": news.createdBy,
                    //                    "message": news.title,
                    //                    "url": news.url
                    //                };
                    //                data.push(temp);
                    //
                    //            }
                    //            callbackInner(err, null);
                    //        });
                    //    }
                    //], function (err, result) {
                    //    callbackInner(null, data);
                    //});

                },
                function (callbackInner) {       //questions
                    questionService.getQuestionByAdoptedReplyService(user.community._id, function (err, results) {
                        callbackInner(err, results);
                    });
                },
                function (callbackInner) {
                    specialTopics.find({
                        community: user.community._id,
                        isValid: true
                    }, '_id title imageURL dateLastModified').sort('-dateCreated').limit(1)
                        .exec(function (err, results) {
                            var data = [];
                            if (results != null && results.length > 0) {
                                data.push(results[0])
                            }
                            data.forEach(function (topic) {
                                topic._doc['url'] = TopicsHost + '/' + topic._id + '.html'
                            });
                            callbackInner(null, data);
                        });
                },
                function (callbackInner) {

                    Users.find({
                        'userType': 'talent',
                        'community': user.community._id
                    }, '_id userPortrait nickName images speciality authenticationStatus').populate('userPortrait', 'value gender')
                        .exec(function (err, results) {
                            if (results != null) {
                                results.forEach(function (user) {
                                    user._doc['gender'] = user._doc.userPortrait.gender;
                                    user._doc.userPortrait = user._doc.userPortrait.value;
                                    user._doc['tag'] = user.speciality;
                                    user.speciality = undefined;
                                });
                                if (results.length > 2) {
                                    var num = toolUtil.getRandomNumArray(2, results.length);
                                    var res = [];
                                    res.push(results[num[0]]);
                                    res.push(results[num[1]]);
                                    callbackInner(null, res);
                                } else {
                                    callbackInner(err, results);
                                }
                            } else {
                                callbackInner(null, null);
                            }
                        });

                    //QuestionReplyStatistics.find({'community': user.community._id}, '-_id user replyCount tag').populate('tag', 'value')
                    //    .populate('user', '_id nickName images userPortrait').sort('-replyCount').exec(function (err, results) {
                    //        if (results != null && results.length > 0) {
                    //            var newArray = [];
                    //            var provisionalTable = {};
                    //            for (var i = 0, item; results[i] != null && (item = results[i].user) != null; i++) {
                    //                if (!provisionalTable[item]) {
                    //                    newArray.push(results[i]);
                    //                    provisionalTable[item] = true;
                    //                }
                    //            }
                    //            results = newArray;
                    //            if (results.length > 2) {
                    //                results = results.splice(0, 2)
                    //            }
                    //            async.each(results, function (result, callback) {
                    //                userPortrait.findOne({_id: result.user.userPortrait}, 'value', function (err, por) {
                    //                    if (por != null) {
                    //                        result._doc.user._doc.userPortrait = por.value;
                    //                    }
                    //                    if (result.tag != null) {
                    //                        result._doc.user._doc['tag'] = result.tag.value;
                    //                    }
                    //                    result.replyCount = undefined;
                    //                    callback();
                    //                });
                    //            }, function (err) {
                    //                if (err) {
                    //                    callbackInner(err, null);
                    //                } else {
                    //                    callbackInner(null, results);
                    //                }
                    //            });
                    //        }
                    //    });
                }
            ], callback)
        }
    });
};


//1.5.0

exports.homePageBannerService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED)
        } else {
            BannerBind.find({community: user.community._id, type: 1}).sort('-displayOrder')
                .populate('bannerId', '_id contentId openType contentCreatedBy contentUrl imageURL')
                .exec(function (err, result) {
                    var data = [];
                    if (result != null) {
                        result.forEach(function (banner) {
                            data.push(banner.bannerId);
                        })
                    }
                    callback(null, data);
                })
        }
    })
};


exports.homePageFreshNewsService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED, null)
        } else {
            var data = [];
            BannerBind.find({community: user.community._id, type: 2}).sort('-displayOrder').limit(3)
                .populate('bannerId', '_id contentId openType contentCreatedBy contentUrl message tag bgColor')
                .exec(function (err, result) {
                    if (result != null && result.length > 0) {
                        result.sort(function (a, b) {
                            return b.dateCreated - a.dateCreated;
                        });
                        var sql = 'SELECT * FROM log_read WHERE user_id=? AND content_id =?';
                        mysqlUtil.query(sql, [user._id, result[0].bannerId.contentId + ''], function (err, log) {
                            result[0].isNew = log && log.length > 0 ? false : true;

                            result.sort(function (a, b) {
                                return b.displayOrder - a.displayOrder
                            });
                            result.forEach(function (news) {
                                var temp = news.bannerId;
                                temp._doc.isNew = news.isNew ? true : false;
                                data.push(temp);
                            });
                            callback(null, data);
                        })
                    } else {
                        callback(null, data);
                    }
                });
        }
    })
};


exports.homePageQuestionAndActivityService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED, null)
        } else {
            async.series([
                function (callbackInner) {
                    var questions = [];
                    try {
                        restClient.get('http://' + RecommendHost + ':8003?recbyuid=' + user._id, function (data, response) {
                            if (response.statusCode == 200) {
                                data = JSON.parse(data);
                                var qIds = data.rec;
                                logger.info(qIds);
                                //var qIds = ['557a74e54cb63bb251ae5a7d', '557a78004cb63bb251ae5c99', '557a791f4cb63bb251ae5d81', '557a968e0a8045a0145c4819', '557a9c520a8045a0145c500c', '557a9f4b0a8045a0145c54a1']
                                async.eachSeries(qIds, function (id, callback1) {
                                    Question.findOne({_id: id}, function (err, question) {
                                        if (question != null) {
                                            var temp = {
                                                desc: question.desc,
                                                category: question.category,
                                                categoryTag: CategoryName[question.category],
                                                browserCount: question.browserCount + '',
                                                replyCount: question.replies.length + '',
                                                questionId: question._id,
                                                createdBy: question.createdBy
                                            };
                                            if (question.images != null && question.images.length > 0) {
                                                temp.pic = question.images[0].imageURL;
                                            }
                                            questions.push(temp)
                                        }
                                        callback1()
                                    })
                                }, function (err) {
                                    callbackInner(null, questions)
                                })
                            } else {
                                callbackInner(null, questions);
                            }
                        }).on('error', function (err) {
                            logger.error('get recommend error' + err.message);
                            callbackInner(null, questions);
                        });
                    } catch (e) {
                        logger.error('get recommend error' + err.message);
                        callbackInner(null, questions);
                    }
                },
                function (callbackInner) {
                    var activities = [];
                    neighbourActivity.find({
                        status: true,
                        isValid: true,
                        community: user.community._id,
                        createdBy: {$ne: user._id},
                        'partake.user': {$ne: user._id}
                    }).sort('-partakeNum').limit(6).exec(function (err, result) {
                        result.forEach(function (activity) {
                            var temp = {
                                title: activity.title,
                                desc: activity.desc,
                                activityId: activity._id,
                                createdBy: activity.createdBy,
                                category: activity.category,
                                activityType: activity.activityType,
                                browserCount: activity.browserCount + '',
                                replyCount: activity.replies.length + '',
                                categoryTag: CategoryName[activity.category]
                            };
                            if (activity.images != null && activity.images.length > 0) {
                                temp.pic = activity.images[0].imageURL;
                            }
                            activities.push(temp)
                        });
                        callbackInner(null, activities);
                    })
                }
            ], callback)
        }
    })
};

exports.homePageTopicsService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED, null)
        } else {
            specialTopics.find({
                community: user.community._id,
                isValid: true
            }, '_id title imageURL dateLastModified').sort('-dateCreated').limit(2)
                .exec(function (err, results) {
                    results.forEach(function (topic) {
                        topic._doc['url'] = TopicsHost + '/' + topic._id + '.html'
                    });
                    callback(null, results);
                });
        }
    })
};

exports.userSignInService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(ErrorMessage.LOGON_EXPIRED);
        } else {

            if (!user.authenticationStatus) {
                callback({message: '非v用户无法签到'})
            } else {
                var key = 'app:signin:' + moment().format('YYYYMMDD');

                redisClient.SISMEMBER(key, token, function (err, result) {
                    if (result == 1) {
                        callback({message: '今天已经签到过了'})
                    } else {
                        redisClient.sadd(key, token);
                        callback();

                        var input = {
                            userId: token + '',
                            scoreAddCount: signInValue,
                            scoreAddRason: '签到'
                        };

                        input.__type__ = 'com.neighborhoods.service.score.dto.ScoreAddRequestDto';

                        scoreProxy.invoke('addScoreManual', [input], function (err, result) {
                            if (err) {
                                logger.error('Exception happened when addScoreManual ...!' + err.message);
                                callback();
                            } else {
                                var data = JSON.parse(decodeURIComponent(result));
                                logger.info(data);
                                if (data.status == 0) {
                                }

                            }
                        });

                    }
                })
            }
        }
    })
};


exports.randomSetCommunityService = function (token, callback) {
    var result = randomCommunities;

    var num = toolUtil.getRandomNumArray(1, result.length);

    var communityId = result[num[0]];

    exports.setUserCommunityNewService(token, communityId, function (err, result) {
        callback(null, communityId);
    })
};

exports.getUserQuestionStatisticsService = function (token, userId, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            var replyC = 0;
            async.series([
                function (callbackInner) {
                    ugcIndex.count({community: user.community._id, createdBy: userId}, callbackInner);
                },
                function (callbackInner) {
                    ugcReply.find({
                        community: user.community._id,
                        repliedBy: userId
                    }, function (err, result) {
                        var replyCount = 0;
                        if (result != null) {
                            result.forEach(function (temp) {
                                if (temp.ugcReply != null) {
                                    replyCount += temp.ugcReply.length;
                                }
                            })
                        }
                        replyC = replyCount;
                        callbackInner(err, replyCount);
                    });
                },
                function (callbackInner) {
                    AdoptedCount.findOne({user: userId, community: user.community._id}, function (err, result) {
                        if (result == null || replyC == 0) {
                            callbackInner(null, '0%')
                        } else {
                            var v = result.adoptedCount * 100 / replyC;
                            callbackInner(err, Math.round(v) + "%");
                        }
                    });
                },
                function (callbackInner) {
                    QuestionReplyPraise.count({'replyBy': userId}, callbackInner);
                }
            ], callback)
        }
    });
};

/**
 * 用户认证
 * @param token
 * @param req
 * @param callback
 */
exports.authenticateUserService = function (token, req, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            toolUtil.uploadImageService(null, null, req, function (err, images) {
                if (err) {
                    callback(err, null);
                } else {
                    if (images[0] == null) {
                        var msg = {
                            "message": "图片上传失败"
                        };
                        callback(msg, null);
                    } else {
                        userAuthentication.findOne({
                            user: user._id,
                            community: user.community._id,
                            isValid: true
                        }, '', function (err, result) {
                            if (result != null) {
                                result.imageURL = images[0];
                                result.save(callback);
                            } else {
                                var temp = new userAuthentication();
                                temp.user = user._id;
                                temp.community = user.community._id;
                                temp.imageURL = images[0];
                                temp.save(callback);
                            }
                        });
                    }
                }
            })
        }
    });
};

exports.authenticateUserByPromotionCodeService = function (code, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null)
        } else {
            promotionCode.findOne({
                code: code,
                expirationDate: {$gte: new Date()}
            }, function (err, result) {
                if (result == null) {
                    var message = {
                        message: '推广码错误，请重新输入'
                    };
                    callback(message, null)
                } else {
                    async.series([
                        function (callbackInner) {
                            callbackInner(null, null)
                        },
                        function (callbackInner) {
                            userAuthentication.findOne({
                                user: user._id,
                                community: user.community._id,
                                isValid: true
                            }, '', function (err, result) {
                                if (result != null) {
                                    result.promotionCode = code;
                                    result.status = true;
                                    result.save(callbackInner);
                                } else {
                                    var temp = new userAuthentication();
                                    temp.user = user._id;
                                    temp.community = user.community._id;
                                    temp.promotionCode = code;
                                    temp.status = true;
                                    temp.save(callbackInner);
                                }
                            });
                        },
                        function (callbackInner) {
                            Users.update({_id: user._id}, {authenticationStatus: true}, callbackInner)
                        },
                        function (callbackInner) {
                            var data = [];
                            roleAction.find({role: 'vip'}).populate('action', 'tag').exec(function (err, results) {
                                if (results != null) {
                                    results.forEach(function (temp) {
                                        data.push(temp.action.tag);
                                    })
                                }
                                var res = {
                                    auth: data,
                                    vStatus: 1
                                };
                                callbackInner(err, res);
                            });
                        },
                        function (callbackInner) {
                            toolUtil.setUserByToken(token);
                            callbackInner();
                        },
                        function (callbackInner) {

                            var message = "你好，你的V认证已经通过，我们将为V用户提供更多，更好的服务，也让你在小区中更与众不同。";
                            toolUtil.pushCustomerServiceMessage(user, message);

                            callbackInner(null, null);
                        }
                    ], callback);
                }
            });
        }
    })
};
/**
 * 验证邀请码
 */
exports.validateInvitationCodeService = function (token, code, callback) {

    Users.findOne({invitationCode: code}, function (err, user) {
        if (user == null) {
            var msg = {
                message: '您输入的邀请码不存在，请重新输入'
            };
            callback(msg, null);
        } else if (user._id == token) {
            var msg = {
                message: '无法邀请自己'
            };
            callback(msg, null);
        } else {
            callback(null, user);
        }
    })
};

/**
 * 绑定邀请关系
 * @param token
 * @param user
 * @param invitationCode
 * @param deviceId
 */
exports.bindInvitationCodeService = function (token, user, invitationCode, deviceId) {
    Users.update({_id: token}, {invitedBy: user._id}).exec(function (err, result) {
        toolUtil.setUserByToken(token)
    });

    var temp = new deviceCodeBind();
    temp.invitationCode = invitationCode;
    temp.deviceId = deviceId;
    temp.user = token;
    temp.save();
};

exports.getUserAuthenticationStatusService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err, null);
        } else {
            userAuthentication.findOne({
                user: user._id,
                isValid: true,
                community: user.community._id
            }, 'status', function (err, result) {
                var data;
                if (result == null) {
                    data = {
                        "status": 0
                    }
                } else {
                    if (result.status) {
                        data = {
                            "status": 1
                        }
                    } else {
                        data = {
                            "status": 2
                        }
                    }
                }
                callback(err, data);
            })
        }
    })
};

exports.getUserInvitedCodeService = function (token, callback) {
    Users.findOne({_id: token}, 'invitedBy', function (err, result) {
        var invitedCode = '';
        if (result != null && result.invitedBy != null && result.invitedBy.invitationCode != null) {
            invitedCode = result.invitedBy.invitationCode;
        }
        callback(null, invitedCode);
    }).populate('invitedBy', 'invitationCode')
};


exports.getMyVoucherListService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {
            var array = [];
            var userId = user._id + '';
            var sql = 'select * from voucher_type n,voucher_user_bind m where m.user_id=? and m.voucher_type_id=n.id';
            mysqlUtil.query(sql, userId, function (err, result) {
                console.log(result);
                if (result != null && result.length > 0) {
                    async.each(result, function (temp, callbackInner) {
                        if (temp.reward_source == 2) {
                            Users.findOne({_id: temp.invited_user}, function (err, invitedUser) {
                                var status = new Date().getTime() > temp.expire_time ? 2 : temp.is_use;
                                var data = {
                                    id: temp.id,
                                    voucherSource: '邀请邻居' + invitedUser.nickName,
                                    cardNo: temp.card_no,
                                    voucherName: temp.voucher_name,
                                    voucherValue: temp.voucher_val,
                                    startTime: moment(new Date(temp.create_time)).format('YYYY-MM-DD'),
                                    endTime: moment(new Date(temp.expire_time)).format('YYYY-MM-DD'),
                                    status: status                           //0,未消费；1，已消费；2，已过期
                                };
                                array.push(data);
                                callbackInner();
                            })
                        } else if (temp.reward_source == 1) {
                            var status = new Date().getTime() > temp.expire_time ? 2 : temp.is_use;
                            var data = {
                                id: temp.id,
                                voucherSource: 'V认证',
                                cardNo: temp.card_no,
                                voucherName: temp.voucher_name,
                                voucherValue: temp.voucher_val,
                                startTime: moment(new Date(temp.create_time)).format('YYYY-MM-DD'),
                                endTime: moment(new Date(temp.expire_time)).format('YYYY-MM-DD'),
                                status: status                           //0,未消费；1，已消费；2，已过期
                            };
                            array.push(data);
                            callbackInner();
                        } else {
                            callbackInner();
                        }
                    }, function (err) {

                        array.sort(function (a, b) {
                            if (a.status != 0 && b.status == 0) {
                                return 1;
                            } else {
                                return b.startTime - a.startTime;
                            }
                        });
                        callback(err, array);
                    })
                } else {
                    callback(null, array);
                }
            });
        }
    })
};

exports.getVoucherDetailService = function (voucherId, token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {
            async.series([
                function (callbackInner) {
                    var sql = 'select card_no,user_id from voucher_user_bind where id=?';
                    mysqlUtil.query(sql, voucherId, function (err, result) {
                        if (result != null && result.length > 0) {
                            var voucher = {
                                cardNo: result[0].card_no,
                                cardUrl: cardUrl + '?backUrl=' + encodeURIComponent(cardH5Url + '?cardNo=' + result[0].card_no + '&userId=' + result[0].user_id + '&html=voucher')
                            };
                            callbackInner(err, voucher);
                        } else {
                            var msg = {
                                message: '代金券不存在'
                            };
                            logger.error('getVoucherDetailService' + err);
                            callbackInner(msg, null);
                        }
                    })
                },
                function (callbackInner) {
                    var sql = 'select r.retailer_name,r.address,r.phone,r.retailer_icon from retailer r,retailer_community_bind b where b.community_id=? and b.retailer_id=r.id';
                    mysqlUtil.query(sql, user.community._id, function (err, result) {
                        result.forEach(function (temp) {
                            if (temp.retailer_icon == null || temp.retailer_icon == '') {
                                temp.retailer_icon = 'http://66xiaoqu.babytreeimg.com/group1/M00/00/04/rB75BFTZwwWAF2L-AABUqY8vmBc771.png'
                            }
                        });
                        callbackInner(err, result);
                    })
                }
            ], callback)
        }
    })
};


//================================================== Web后台管理 ==============================================


/**
 * 根据分页查找全部用户
 */
exports.getAllUserService = function (page, callback) {
    var index = Number(page) * listPageSize;
    listPageSize = 10000;//暂时先设置为10000，分页做了再修改
    Users.find(null).populate('community', 'communityName').skip(index).limit(listPageSize).sort('-dateCreated')
        .exec(function (err, results) {
            if (results == undefined || results == null) {
                var msg = {
                    "message": 'get err'
                };
                callback(msg, null);
            } else {
                callback(null, results);
            }
        })
};

exports.findByNameORPhoneService = function (page, input, callback) {

    var query1 = {nickName: new RegExp(input.userName)};

    var query2 = {mobilePhone: new RegExp(input.userPhoneNO)};

    var index = Number(page) * listPageSize;

    if (input.userName == null) {
        query1 = null;
    }
    if (input.userPhoneNO == null) {
        query2 = null;
    }

    //Users.find({$or:[{ nickName:  new RegExp(input.userName) }, { mobilePhone: new RegExp(input.userPhoneNO)}]}).skip(index * page).limit(listPageSize).sort('-dateCreated')
    Users.find({$and: [query1, query2]}).skip(index * page).limit(listPageSize).sort('-dateCreated')
        .exec(function (err, results) {
            if (results == undefined || results == null) {
                var msg = {
                    "message": 'get err'
                };
                callback(msg, null);
            } else {
                callback(null, results);
            }
        })
};

exports.registerUserFromBackOfficeService = function (user, callback) {

    var tempUser = new Users();
    tempUser.userName = user.userName;
    tempUser.email = user.email;
    tempUser.mobilePhone = user.mobilePhone;
    tempUser.userPassword = user.userPassword;
    tempUser.community = user.community;
    tempUser.domainOfExpertise = user.domainOfExpertise;


    if (user.userName) {
        tempUser.huanxinUserName = user.userName;
    } else if (user.email) {
        tempUser.huanxinUserName = user.email;
    } else if (user.nickName) {
        tempUser.nickName = user.nickName;
    } else {
        tempUser.huanxinUserName = user.mobilePhone;
        tempUser.nickName = user.mobilePhone.substr(6);
    }


    tempUser.huanxinPassword = user.userPassword;

    tempUser.community = user.community;
    tempUser.save(callback);

    //环信注册开始
    var http = require('http');

    //构造post数据
    if (user.userName) {

        var post_data = {
            username: user.userName,
            password: user.userPassword
        };
        post_data = JSON.stringify(post_data);
        //logger.debug('post_data:'+post_data);
    } else if (user.email) {
        var post_data = {
            username: user.email,
            password: user.userPassword
        };
        post_data = JSON.stringify(post_data);
        //logger.debug('post_data:'+post_data);
    } else {
        var post_data = {
            username: user.mobilePhone,
            password: user.userPassword
        };
        post_data = JSON.stringify(post_data);
        //logger.debug('post_data:'+post_data);
    }

    //构造链接选项
    var urlOpts = {
        host: 'a1.easemob.com',
        path: '/66xiaoqu/' + huanxinEnv + '/users',
        port: '80',
        method: 'POST',
        headers: {
            "Content-Type": "application/json",
            "Content-Length": post_data.length
        }
    };

    //向环信提交请求
    var request = http.request(urlOpts, function (response) {
        response.on('data', function (chunk) {//请求成功的情况
            logger.debug(chunk.toString());

        });
    }).on('error', function (e) {//请求失败的情况
        logger.debug('error:' + e.stack);
        //删除在数据库中添加的用户
        userService.deleteService(user.userName, user.email, user.mobilePhone, function (err) {
            if (err) {
                logger.error("Failed to register this user - Failed to delete user - " + err.message);
                callback(err);
            } else {
                logger.error("Failed to register this user - succeed to delete user - " + err.message);
                callback(err);
            }
        });
    });
    // write data to request body
    request.write(post_data + "\n");
    request.end();
    //环信注册结束

};


/**
 * userService.js
 *搜索用户
 *author：chenjinzhuan
 * */
exports.searchBackOfficeUserService = function (input, callback) {

    var query1 = {nickName: new RegExp(input.nickName)};

    var query2 = {mobilePhone: new RegExp(input.userPhoneNO)};

    //var query3 = {'communityName': input.communityName};

    var query4 = {dateCreated: {"$gte": new Date(input.dateStart)}};

    var query5 = {dateCreated: {"$lt": new Date(input.dateEnd)}};

    //var index = Number(page)* listPageSize;

    if (input.nickName == null || input.nickName == '') {
        query1 = null;
    }
    if (input.userPhoneNO == null || input.userPhoneNO == '') {
        query2 = null;
    }
    if (input.dateStart == null || input.dateStart == '') {
        query4 = null;
    }
    if (input.dateEnd == null || input.dateEnd == '') {
        query5 = null;
    }


    async.waterfall([
        //根据昵称、手机、起始日期和终止日期查询
        function (callbackInner) {
            //Users.find({$or:[{ nickName:  new RegExp(input.userName) }, { mobilePhone: new RegExp(input.userPhoneNO)}]}).skip(index * page).limit(listPageSize).sort('-dateCreated')
            //Users.find({$and: [query1, query2, query4, query5]}).populate('community', 'communityName').skip(index * page).limit(listPageSize).sort('-dateCreated')
            Users.find({$and: [query1, query2, query4, query5]}).populate('community', 'communityName').sort('-dateCreated')
                .exec(function (err, results) {
                    if (results == undefined || results == null) {
                        var msg = {
                            "message": 'get err'
                        };
                        callback(msg, null);
                    } else {
                        return callbackInner(null, results);
                    }
                });
        },
        //根据小区名称单独查询
        function (results) {
            if (input.communityName == null || input.communityName == '') {
                return callback(null, results);
            }
            for (var i = results.length - 1; i >= 0; i--) {
                if (results[i].community == null || results[i].community.communityName != input.communityName) {
                    results.splice(i, 1);
                }
            }
            return callback(null, results);
        }
    ]);
};

/**
 * userService.js
 * 后台管理用户登录
 *author：chenjinzhuan
 * */
exports.adminLoginService = function (input, callback) {

    var userName = input.userName;
    var password = input.password;

    adminUsers.find({'userName': userName, 'password': password}, function (err, results) {
        if (err) {//异常
            return callback(err, null);
        } else if (results == null || results.length == 0) {//用户名密码不匹配或者用户不存在
            return callback(null, {status: false});
        } else {//用户名密码匹配成功
            return callback(null, {status: true});
        }
    });
};

/**
 *
 * @param communityId
 * @param status
 * @param callback
 */
exports.getAuthenticationUserListService = function (communityId, status, nickname, page, callback) {
    logger.info(communityId + "/" + status + "/" + nickname);

    var opt = {};

    if (communityId == '1' && status == '1') {
        opt = {
            isValid: true
        }
    } else if (communityId == '1' && status != '1') {
        opt = {
            status: status,
            isValid: true
        }
    } else if (communityId != '1' && status == '1') {
        opt = {
            community: communityId,
            isValid: true
        }
    } else {
        opt = {
            community: communityId,
            status: status,
            isValid: true
        }
    }
    async.series([

        function (callbackInner) {


            if (nickname != '1') {

                Users.find({nickName: {$regex: nickname}}, "_id").exec(function (err, result) {

                    var userIds = [];
                    for (var i = 0; i < result.length; i++) {
                        userIds[i] = result[i];
                    }
                    opt.user = {$in: userIds};


                    var index = (Number(page) - 1) * listPageSize;
                    userAuthentication.find(opt, 'user community imageURL promotionCode status dateCreated').skip(index).limit(listPageSize)
                        .populate('user', '_id nickName images roomUnit roomNumber')
                        .populate('community', '_id communityName').sort('-dateCreated').exec(callbackInner);
                })
            } else {
                var index = (Number(page) - 1) * listPageSize;
                userAuthentication.find(opt, 'user community imageURL promotionCode status dateCreated').skip(index).limit(listPageSize)
                    .populate('user', '_id nickName images roomUnit roomNumber')
                    .populate('community', '_id communityName').sort('-dateCreated').exec(callbackInner);
            }
        },
        function (callbackInner) {
            userAuthentication.count(opt, callbackInner);
        }
    ], callback)
};


/**
 * 审核用户认证
 */
exports.examineUserAuthenticateService = function (body, callback) {
    var communityId;
    var huanxinUser;

    userAuthentication.findOne({user: body.user, community: body.community, isValid: true}, function (err, result) {
        if (body.status && result.status) {
            var message = {
                message: '已经通过认证'
            };
            callback(message, null)
        } else {
            async.series([
                function (callbackInner) {
                    userAuthentication.update({
                        'user': body.user,
                        'community': body.community,
                        isValid: true
                    }, {'status': body.status}, callbackInner);
                },
                function (callbackInner) {
                    Users.findOne({_id: body.user}, 'community huanxinUserName nickName images invitedBy').populate('community', '_id communityName').exec(function (err, user) {
                        communityId = user.community._id;
                        huanxinUser = user;
                        callbackInner(null, user.invitedBy);
                    });
                },
                function (callbackInner) {
                    if (body.community == communityId) {
                        Users.update({_id: body.user}, {'authenticationStatus': body.status}, callbackInner);
                        toolUtil.setUserByToken(body.user);
                    } else {
                        callbackInner(null, null);
                    }
                },
                function (callbackInner) {
                    if (body.status && body.community == communityId) {

                        var message = "你好，你的V认证已经通过，我们将为V用户提供更多，更好的服务，也让你在小区中更与众不同。";
                        toolUtil.pushCustomerServiceMessage(huanxinUser, message);
                        callbackInner(null, null);
                    } else {
                        callbackInner(null, null);
                    }
                },

                function (callbackInner) {
                    if (body.community == communityId) {
                        var status = 0;
                        if (body.status) {
                            status = 1;
                        } else {
                            status = 2;
                        }
                        //个推
                        var content = {
                            f: 3,
                            vStatus: status
                        };
                        var pushData = {
                            uList: [body.user],
                            content: content
                        };
                        toolUtil.putMessageTransmissionPushMQ(pushData);
                    }
                    callbackInner(null, null);
                },
                //更新最后修改日期
                function (callbackInner) {
                    userAuthentication.update({
                        'user': body.user,
                        'community': body.community
                    }, {dateLastModified: new Date()}, callbackInner);
                },
                function (callbackInner) {
                    toolUtil.setUserByToken(body.user);
                    callbackInner();
                }
            ], callback)
        }
    });
};

exports.refuseUserAuthenticateService = function (id, body, callback) {

    var communityId;
    var huanxinUser;

    async.series([
        function (callbackInner) {
            userAuthentication.update({_id: id}, {isValid: false, refusalReason: body.message}, callbackInner);
        },
        function (callbackInner) {

            Users.findOne({_id: body.userId}, 'huanxinUserName community nickName images').populate('community', '_id communityName').exec(function (err, result) {
                communityId = result.community._id;
                huanxinUser = result;
                callbackInner(null, null);
            });
        },
        function (callbackInner) {
            if (body.community == communityId) {

                var message = body.message;
                toolUtil.pushCustomerServiceMessage(huanxinUser, message);

                callbackInner(null, null);
            } else {
                callbackInner(null, null);
            }
        },
        function (callbackInner) {
            if (body.community == communityId) {
                //个推
                var content = {
                    f: 3,
                    vStatus: 0
                };
                var pushData = {
                    uList: [body.userId],
                    content: content
                };
                toolUtil.putMessageTransmissionPushMQ(pushData);
            }
            callbackInner(null, null);
        }
    ], callback)
};

exports.getRecentContactPersonService = function (token, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {

            recentContact.find({
                userHuanxin: user.huanxinUserName,
                $and: [{otherHuanxin: /\b((?!500500)\w)+\b/}, {otherHuanxin: {$ne: '66customerservice'}}, {otherHuanxin: {$ne: 'superservice'}}]
            }).sort('-time').limit(10).exec(function (err, result) {
                var huanxinIds = [];
                if (result != null && result.length > 0) {
                    result.forEach(function (huanxin) {
                        huanxinIds.push(huanxin.otherHuanxin);
                    })
                }
                var data = [];
                async.eachSeries(huanxinIds, function (id, c1) {
                    Users.findOne({huanxinUserName: id}, '_id nickName images userType authenticationStatus roomUnit', function (err, result) {
                        if (result != null) {
                            data.push(result);
                        }
                        c1();
                    })
                }, function (err) {
                    callback(err, data);
                });
            });
        }
    })
};

exports.getScoreRank = function (token, pageNo, callback) {
    toolUtil.getUserByToken(token, function (err, user) {
        if (err) {
            callback(err)
        } else {

            var pageSize = 10;

            var fromIndex = (pageNo - 1) * pageSize;
            var toIndex = fromIndex + (pageSize - 1);

            var now = new Date();
            now.setDate(now.getDate() - 1);
            var date = now.getFullYear() + "" + (parseInt(now.getMonth() + 1) < 10 ? '0' + (now.getMonth() + 1) : +(now.getMonth() + 1) ) + (parseInt(now.getDate()) < 10 ? '0' + (now.getDate()) : +(now.getDate()) );

            var communityId = user.community._id;

            var key = "score:rank:community:" + communityId + ":date:" + date;

            logger.info(key);

            redisClient.zrevrange(key, fromIndex, toIndex, 'WITHSCORES', function (err, result) {


                var userList = [];
                var tempResult = [];

                for (var i = 0; i < result.length; i++) {
                    logger.info(i / 2);
                    if (i % 2 == 0) {
                        tempResult.push({
                            value: result[i],
                            score: result[i + 1]
                        });
                    }
                }

                async.eachSeries(tempResult, function (temp, callbackInner) {
                    Users.findOne({_id: temp.value}, function (err, user) {
                        user._doc.ratio = temp.score;
                        userList.push(user);
                        callbackInner();
                    });
                }, function (err) {
                    callback(err, userList);
                });
            });
        }
    })
};

/*  宝宝树66小区二次改造    add   guo.xiaomin  20170921   start   */
exports.isModeratorManager = function (mobilephone, callback) {
    Users.count({'mobilePhone': mobilephone, userRole: 4}, function (err, tempCount) {
        callback(err, tempCount > 0 ? true : false);
    });
};

exports.getUserIdByMobilePhone = function (mobilephone, callback) {
    Users.findOne({'mobilePhone': mobilephone}, {'_id': 1}, function (err, tempId) {
        if(tempId) {
            callback(err, tempId._doc._id);
        } else {
            callback(err, null);
        }
    });
};
/*  宝宝树66小区二次改造    add   guo.xiaomin  20170921   end   */